heads up notifications, v0.1
1. re-name intruder alerts to heads up notifications 2. use interrupt for the verb form, instead of intrude 3. new policy: no full screen, high priority, screen on, not locked or dreaming 4. controlled by global setting, with an observer 5. only content view for now, expandable is a todo to turn it on: adb shell settings put global heads_up_enabled 1 calendar notifications (not pop-up) work well. Change-Id: I253418c217d0a5cf81dc2fa001f4bad90fafcce5
This commit is contained in:
@ -15,6 +15,7 @@
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:exitFadeDuration="@android:integer/config_mediumAnimTime">
|
||||
<item android:state_pressed="true" android:drawable="@drawable/intruder_bg_pressed" />
|
||||
android:exitFadeDuration="@android:integer/config_mediumAnimTime">
|
||||
<item android:state_pressed="true"
|
||||
android:drawable="@drawable/heads_up_notification_bg_pressed" />
|
||||
</selector>
|
Before Width: | Height: | Size: 272 B After Width: | Height: | Size: 272 B |
@ -19,7 +19,7 @@
|
||||
-->
|
||||
|
||||
<!-- android:background="@drawable/status_bar_closed_default_background" -->
|
||||
<com.android.systemui.statusbar.policy.IntruderAlertView
|
||||
<com.android.systemui.statusbar.policy.HeadsUpNotificationView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
@ -29,12 +29,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/contentHolder"
|
||||
android:background="@drawable/intruder_window_bg"
|
||||
android:background="@drawable/heads_up_window_bg"
|
||||
/>
|
||||
<!-- <ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/title_bar_shadow"
|
||||
android:scaleType="fitXY"
|
||||
/> -->
|
||||
</com.android.systemui.statusbar.policy.IntruderAlertView>
|
||||
</com.android.systemui.statusbar.policy.HeadsUpNotificationView>
|
@ -27,7 +27,7 @@
|
||||
<color name="notification_list_shadow_top">#80000000</color>
|
||||
<drawable name="recents_callout_line">#99ffffff</drawable>
|
||||
<drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable>
|
||||
<drawable name="intruder_bg_pressed">#ff33B5E5</drawable>
|
||||
<drawable name="heads_up_notification_bg_pressed">#ff33B5E5</drawable>
|
||||
<drawable name="notification_header_bg">#FF000000</drawable>
|
||||
<color name="notification_panel_scrim_color">#B0000000</color>
|
||||
</resources>
|
||||
|
@ -34,7 +34,7 @@
|
||||
<item name="android:wallpaperIntraOpenExitAnimation">@anim/wallpaper_recents_launch_from_launcher_exit</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.StatusBar.IntruderAlert"
|
||||
<style name="TextAppearance.StatusBar.HeadsUp"
|
||||
parent="@*android:style/TextAppearance.StatusBar">
|
||||
</style>
|
||||
|
||||
@ -154,9 +154,9 @@
|
||||
<style name="Animation.StatusBar">
|
||||
</style>
|
||||
|
||||
<style name="Animation.StatusBar.IntruderAlert">
|
||||
<item name="android:windowEnterAnimation">@anim/priority_alert_enter</item>
|
||||
<item name="android:windowExitAnimation">@anim/priority_alert_exit</item>
|
||||
<style name="Animation.StatusBar.HeadsUp">
|
||||
<item name="android:windowEnterAnimation">@anim/heads_up_enter</item>
|
||||
<item name="android:windowExitAnimation">@anim/heads_up_exit</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.StatusBar.PhoneTicker"
|
||||
|
@ -35,10 +35,13 @@ import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.dreams.DreamService;
|
||||
import android.service.dreams.IDreamManager;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
@ -83,16 +86,19 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
|
||||
protected static final int MSG_OPEN_SEARCH_PANEL = 1024;
|
||||
protected static final int MSG_CLOSE_SEARCH_PANEL = 1025;
|
||||
protected static final int MSG_SHOW_INTRUDER = 1026;
|
||||
protected static final int MSG_HIDE_INTRUDER = 1027;
|
||||
protected static final int MSG_SHOW_HEADS_UP = 1026;
|
||||
protected static final int MSG_HIDE_HEADS_UP = 1027;
|
||||
|
||||
protected static final boolean ENABLE_INTRUDERS = false;
|
||||
protected static final boolean ENABLE_HEADS_UP = true;
|
||||
// scores above this threshold should be displayed in heads up mode.
|
||||
private static final int INTERRUPTION_THRESHOLD = 10;
|
||||
|
||||
// Should match the value in PhoneWindowManager
|
||||
public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
|
||||
|
||||
public static final int EXPANDED_LEAVE_ALONE = -10000;
|
||||
public static final int EXPANDED_FULL_OPEN = -10001;
|
||||
private static final String SETTING_HEADS_UP = "heads_up_enabled";
|
||||
|
||||
protected CommandQueue mCommandQueue;
|
||||
protected IStatusBarService mBarService;
|
||||
@ -102,7 +108,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
protected NotificationData mNotificationData = new NotificationData();
|
||||
protected NotificationRowLayout mPile;
|
||||
|
||||
protected StatusBarNotification mCurrentlyIntrudingNotification;
|
||||
protected StatusBarNotification mCurrentlyInterruptingNotification;
|
||||
|
||||
// used to notify status bar for suppressing notification LED
|
||||
protected boolean mPanelSlightlyVisible;
|
||||
@ -116,6 +122,11 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
|
||||
protected int mLayoutDirection;
|
||||
private Locale mLocale;
|
||||
protected boolean mUseHeadsUp = true;
|
||||
|
||||
protected IDreamManager mDreamManager;
|
||||
KeyguardManager mKeyguardManager;
|
||||
PowerManager mPowerManager;
|
||||
|
||||
// UI-specific methods
|
||||
|
||||
@ -155,6 +166,19 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}
|
||||
};
|
||||
|
||||
final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
mUseHeadsUp = ENABLE_HEADS_UP && 0 != Settings.Global.getInt(
|
||||
mContext.getContentResolver(), SETTING_HEADS_UP, 0);
|
||||
Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
|
||||
if (!mUseHeadsUp) {
|
||||
Log.d(TAG, "dismissing any existing heads up notification on disable event");
|
||||
mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
|
||||
@Override
|
||||
public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fillInIntent) {
|
||||
@ -204,11 +228,21 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
|
||||
mDisplay = mWindowManager.getDefaultDisplay();
|
||||
|
||||
mDreamManager = IDreamManager.Stub.asInterface(
|
||||
ServiceManager.checkService(DreamService.DREAM_SERVICE));
|
||||
mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||
|
||||
mProvisioningObserver.onChange(false); // set up
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
|
||||
mProvisioningObserver);
|
||||
|
||||
mHeadsUpObserver.onChange(false); // set up
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Global.getUriFor(SETTING_HEADS_UP), true,
|
||||
mHeadsUpObserver);
|
||||
|
||||
mBarService = IStatusBarService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
||||
|
||||
@ -398,7 +432,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}
|
||||
}
|
||||
|
||||
public void dismissIntruder() {
|
||||
public void dismissHeadsUp() {
|
||||
// pass
|
||||
}
|
||||
|
||||
@ -677,13 +711,13 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
return new NotificationClicker(intent, pkg, tag, id);
|
||||
}
|
||||
|
||||
private class NotificationClicker implements View.OnClickListener {
|
||||
protected class NotificationClicker implements View.OnClickListener {
|
||||
private PendingIntent mIntent;
|
||||
private String mPkg;
|
||||
private String mTag;
|
||||
private int mId;
|
||||
|
||||
NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
|
||||
public NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
|
||||
mIntent = intent;
|
||||
mPkg = pkg;
|
||||
mTag = tag;
|
||||
@ -730,9 +764,6 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
// close the shade if it was open
|
||||
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
|
||||
visibilityChanged(false);
|
||||
|
||||
// If this click was on the intruder alert, hide that instead
|
||||
// mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -997,18 +1028,30 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
setAreThereNotifications();
|
||||
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
|
||||
|
||||
// See if we need to update the intruder.
|
||||
if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) {
|
||||
if (DEBUG) Log.d(TAG, "updating the current intruder:" + notification);
|
||||
// See if we need to update the heads up.
|
||||
if (ENABLE_HEADS_UP && oldNotification == mCurrentlyInterruptingNotification) {
|
||||
if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification);
|
||||
// XXX: this is a hack for Alarms. The real implementation will need to *update*
|
||||
// the intruder.
|
||||
if (notification.getNotification().fullScreenIntent == null) { // TODO(dsandler): consistent logic with add()
|
||||
if (DEBUG) Log.d(TAG, "no longer intrudes!");
|
||||
mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
|
||||
// the heads up.
|
||||
if (!shouldInterrupt(notification)) {
|
||||
if (DEBUG) Log.d(TAG, "no longer interrupts!");
|
||||
mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean shouldInterrupt(StatusBarNotification notification) {
|
||||
boolean interrupt = notification.getNotification().fullScreenIntent == null
|
||||
&& notification.getScore() >= INTERRUPTION_THRESHOLD
|
||||
&& mPowerManager.isScreenOn() && !mKeyguardManager.isKeyguardLocked();
|
||||
try {
|
||||
interrupt = interrupt && !mDreamManager.isDreaming();
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "failed to query dream manager", e);
|
||||
}
|
||||
return interrupt;
|
||||
}
|
||||
|
||||
// Q: What kinds of notifications should show during setup?
|
||||
// A: Almost none! Only things coming from the system (package is "android") that also
|
||||
// have special "kind" tags marking them as relevant for setup (see below).
|
||||
|
@ -45,12 +45,9 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.dreams.DreamService;
|
||||
import android.service.dreams.IDreamManager;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.EventLog;
|
||||
@ -76,7 +73,6 @@ import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.internal.statusbar.StatusBarIcon;
|
||||
import com.android.systemui.EventLogTags;
|
||||
import com.android.systemui.R;
|
||||
@ -90,7 +86,7 @@ import com.android.systemui.statusbar.StatusBarIconView;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
import com.android.systemui.statusbar.policy.DateView;
|
||||
import com.android.systemui.statusbar.policy.IntruderAlertView;
|
||||
import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
|
||||
import com.android.systemui.statusbar.policy.LocationController;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
import com.android.systemui.statusbar.policy.NotificationRowLayout;
|
||||
@ -127,7 +123,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
// 1020-1030 reserved for BaseStatusBar
|
||||
|
||||
// will likely move to a resource or other tunable param at some point
|
||||
private static final int INTRUDER_ALERT_DECAY_MS = 0; // disabled, was 10000;
|
||||
private static final int HEADS_UP_DECAY_MS = 0; // disabled, was 10000;
|
||||
|
||||
private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
|
||||
|
||||
@ -169,8 +165,6 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
Display mDisplay;
|
||||
Point mCurrentDisplaySize = new Point();
|
||||
|
||||
IDreamManager mDreamManager;
|
||||
|
||||
StatusBarWindowView mStatusBarWindow;
|
||||
PhoneStatusBarView mStatusBarView;
|
||||
|
||||
@ -230,8 +224,8 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
// the date view
|
||||
DateView mDateView;
|
||||
|
||||
// for immersive activities
|
||||
private IntruderAlertView mIntruderAlertView;
|
||||
// for heads up notifications
|
||||
private HeadsUpNotificationView mHeadsUpNotificationView;
|
||||
|
||||
// on-screen navigation buttons
|
||||
private NavigationBarView mNavigationBarView = null;
|
||||
@ -358,14 +352,11 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
.getDefaultDisplay();
|
||||
mDisplay.getSize(mCurrentDisplaySize);
|
||||
|
||||
mDreamManager = IDreamManager.Stub.asInterface(
|
||||
ServiceManager.checkService(DreamService.DREAM_SERVICE));
|
||||
|
||||
super.start(); // calls createAndAddWindows()
|
||||
|
||||
addNavigationBar();
|
||||
|
||||
if (ENABLE_INTRUDERS) addIntruderView();
|
||||
if (ENABLE_HEADS_UP) addHeadsUpView();
|
||||
|
||||
// Lastly, call to the icon policy to install/update all the icons.
|
||||
mIconPolicy = new PhoneStatusBarPolicy(mContext);
|
||||
@ -424,10 +415,11 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
|
||||
R.color.notification_panel_solid_background)));
|
||||
}
|
||||
if (ENABLE_INTRUDERS) {
|
||||
mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
|
||||
mIntruderAlertView.setVisibility(View.GONE);
|
||||
mIntruderAlertView.setBar(this);
|
||||
if (ENABLE_HEADS_UP) {
|
||||
mHeadsUpNotificationView =
|
||||
(HeadsUpNotificationView) View.inflate(context, R.layout.heads_up, null);
|
||||
mHeadsUpNotificationView.setVisibility(View.GONE);
|
||||
mHeadsUpNotificationView.setBar(this);
|
||||
}
|
||||
if (MULTIUSER_DEBUG) {
|
||||
mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info);
|
||||
@ -833,7 +825,7 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
return lp;
|
||||
}
|
||||
|
||||
private void addIntruderView() {
|
||||
private void addHeadsUpView() {
|
||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
@ -847,11 +839,11 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
PixelFormat.TRANSLUCENT);
|
||||
lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
|
||||
//lp.y += height * 1.5; // FIXME
|
||||
lp.setTitle("IntruderAlert");
|
||||
lp.setTitle("Heads Up");
|
||||
lp.packageName = mContext.getPackageName();
|
||||
lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
|
||||
lp.windowAnimations = R.style.Animation_StatusBar_HeadsUp;
|
||||
|
||||
mWindowManager.addView(mIntruderAlertView, lp);
|
||||
mWindowManager.addView(mHeadsUpNotificationView, lp);
|
||||
}
|
||||
|
||||
public void refreshAllStatusBarIcons() {
|
||||
@ -895,52 +887,31 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
StatusBarIconView iconView = addNotificationViews(key, notification);
|
||||
if (iconView == null) return;
|
||||
|
||||
boolean immersive = false;
|
||||
try {
|
||||
immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
|
||||
}
|
||||
} catch (RemoteException ex) {
|
||||
}
|
||||
|
||||
/*
|
||||
* DISABLED due to missing API
|
||||
if (ENABLE_INTRUDERS && (
|
||||
// TODO(dsandler): Only if the screen is on
|
||||
notification.notification.intruderView != null)) {
|
||||
Log.d(TAG, "Presenting high-priority notification");
|
||||
// special new transient ticker mode
|
||||
// 1. Populate mIntruderAlertView
|
||||
|
||||
if (notification.notification.intruderView == null) {
|
||||
Log.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
|
||||
return;
|
||||
}
|
||||
if (mUseHeadsUp && shouldInterrupt(notification)) {
|
||||
if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
|
||||
// 1. Populate mHeadsUpNotificationView
|
||||
|
||||
// bind the click event to the content area
|
||||
PendingIntent contentIntent = notification.notification.contentIntent;
|
||||
PendingIntent contentIntent = notification.getNotification().contentIntent;
|
||||
final View.OnClickListener listener = (contentIntent != null)
|
||||
? new NotificationClicker(contentIntent,
|
||||
notification.pkg, notification.tag, notification.id)
|
||||
notification.getPackageName(), notification.getTag(), notification.getId())
|
||||
: null;
|
||||
|
||||
mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener);
|
||||
if (mHeadsUpNotificationView.applyContent(notification.getNotification(), listener)) {
|
||||
|
||||
mCurrentlyIntrudingNotification = notification;
|
||||
mCurrentlyInterruptingNotification = notification;
|
||||
|
||||
// 2. Animate mIntruderAlertView in
|
||||
mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
|
||||
// 2. Animate mHeadsUpNotificationView in
|
||||
mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
|
||||
|
||||
// 3. Set alarm to age the notification off (TODO)
|
||||
mHandler.removeMessages(MSG_HIDE_INTRUDER);
|
||||
if (INTRUDER_ALERT_DECAY_MS > 0) {
|
||||
mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
|
||||
// 3. Set alarm to age the notification off (TODO)
|
||||
mHandler.removeMessages(MSG_HIDE_HEADS_UP);
|
||||
if (HEADS_UP_DECAY_MS > 0) {
|
||||
mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, HEADS_UP_DECAY_MS);
|
||||
}
|
||||
}
|
||||
} else
|
||||
*/
|
||||
|
||||
if (notification.getNotification().fullScreenIntent != null) {
|
||||
} else if (notification.getNotification().fullScreenIntent != null) {
|
||||
// Stop screensaver if the notification has a full-screen intent.
|
||||
// (like an incoming phone call)
|
||||
awakenDreams();
|
||||
@ -954,8 +925,8 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
} else {
|
||||
// usual case: status bar visible & not immersive
|
||||
|
||||
// show the ticker if there isn't an intruder too
|
||||
if (mCurrentlyIntrudingNotification == null) {
|
||||
// show the ticker if there isn't already a heads up
|
||||
if (mCurrentlyInterruptingNotification == null) {
|
||||
tick(null, notification, true);
|
||||
}
|
||||
}
|
||||
@ -976,8 +947,8 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
// Recalculate the position of the sliding windows and the titles.
|
||||
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
|
||||
|
||||
if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) {
|
||||
mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
|
||||
if (ENABLE_HEADS_UP && old == mCurrentlyInterruptingNotification) {
|
||||
mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
|
||||
}
|
||||
|
||||
if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0) {
|
||||
@ -1359,12 +1330,12 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
case MSG_CLOSE_PANELS:
|
||||
animateCollapsePanels();
|
||||
break;
|
||||
case MSG_SHOW_INTRUDER:
|
||||
setIntruderAlertVisibility(true);
|
||||
case MSG_SHOW_HEADS_UP:
|
||||
setHeadsUpVisibility(true);
|
||||
break;
|
||||
case MSG_HIDE_INTRUDER:
|
||||
setIntruderAlertVisibility(false);
|
||||
mCurrentlyIntrudingNotification = null;
|
||||
case MSG_HIDE_HEADS_UP:
|
||||
setHeadsUpVisibility(false);
|
||||
mCurrentlyInterruptingNotification = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2487,22 +2458,20 @@ public class PhoneStatusBar extends BaseStatusBar {
|
||||
mCurrentUserId);
|
||||
}
|
||||
|
||||
private void setIntruderAlertVisibility(boolean vis) {
|
||||
if (!ENABLE_INTRUDERS) return;
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
|
||||
}
|
||||
mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
|
||||
private void setHeadsUpVisibility(boolean vis) {
|
||||
if (!ENABLE_HEADS_UP) return;
|
||||
if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
|
||||
mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
public void dismissIntruder() {
|
||||
if (mCurrentlyIntrudingNotification == null) return;
|
||||
public void dismissHeadsUp() {
|
||||
if (mCurrentlyInterruptingNotification == null) return;
|
||||
|
||||
try {
|
||||
mBarService.onNotificationClear(
|
||||
mCurrentlyIntrudingNotification.getPackageName(),
|
||||
mCurrentlyIntrudingNotification.getTag(),
|
||||
mCurrentlyIntrudingNotification.getId());
|
||||
mCurrentlyInterruptingNotification.getPackageName(),
|
||||
mCurrentlyInterruptingNotification.getTag(),
|
||||
mCurrentlyInterruptingNotification.getId());
|
||||
} catch (android.os.RemoteException ex) {
|
||||
// oh well
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.policy;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
@ -27,14 +28,13 @@ import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SwipeHelper;
|
||||
import com.android.systemui.statusbar.BaseStatusBar;
|
||||
|
||||
public class IntruderAlertView extends LinearLayout implements SwipeHelper.Callback {
|
||||
private static final String TAG = "IntruderAlertView";
|
||||
public class HeadsUpNotificationView extends LinearLayout implements SwipeHelper.Callback {
|
||||
private static final String TAG = "HeadsUpNotificationView";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
Rect mTmpRect = new Rect();
|
||||
@ -44,14 +44,14 @@ public class IntruderAlertView extends LinearLayout implements SwipeHelper.Callb
|
||||
BaseStatusBar mBar;
|
||||
private ViewGroup mContentHolder;
|
||||
|
||||
private RemoteViews mIntruderRemoteViews;
|
||||
private Notification mHeadsUp;
|
||||
private OnClickListener mOnClickListener;
|
||||
|
||||
public IntruderAlertView(Context context, AttributeSet attrs) {
|
||||
public HeadsUpNotificationView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public IntruderAlertView(Context context, AttributeSet attrs, int defStyle) {
|
||||
public HeadsUpNotificationView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
setOrientation(LinearLayout.VERTICAL);
|
||||
@ -64,9 +64,9 @@ public class IntruderAlertView extends LinearLayout implements SwipeHelper.Callb
|
||||
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
|
||||
|
||||
mContentHolder = (ViewGroup) findViewById(R.id.contentHolder);
|
||||
if (mIntruderRemoteViews != null) {
|
||||
if (mHeadsUp != null) {
|
||||
// whoops, we're on already!
|
||||
applyIntruderContent(mIntruderRemoteViews, mOnClickListener);
|
||||
applyContent(mHeadsUp, mOnClickListener);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,8 +92,8 @@ public class IntruderAlertView extends LinearLayout implements SwipeHelper.Callb
|
||||
}
|
||||
|
||||
public void onChildDismissed(View v) {
|
||||
Log.v(TAG, "User swiped intruder to dismiss");
|
||||
mBar.dismissIntruder();
|
||||
Log.v(TAG, "User swiped heads up to dismiss");
|
||||
mBar.dismissHeadsUp();
|
||||
}
|
||||
|
||||
public void onBeginDrag(View v) {
|
||||
@ -134,33 +134,34 @@ public class IntruderAlertView extends LinearLayout implements SwipeHelper.Callb
|
||||
}
|
||||
}
|
||||
|
||||
public void applyIntruderContent(RemoteViews intruderView, OnClickListener listener) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "applyIntruderContent: view=" + intruderView + " listener=" + listener);
|
||||
}
|
||||
mIntruderRemoteViews = intruderView;
|
||||
public boolean applyContent(Notification headsUp, OnClickListener listener) {
|
||||
mHeadsUp = headsUp;
|
||||
mOnClickListener = listener;
|
||||
if (mContentHolder == null) {
|
||||
if (mContentHolder == null) {
|
||||
// too soon!
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (headsUp.contentView == null) {
|
||||
// bad data
|
||||
return false;
|
||||
}
|
||||
mContentHolder.setX(0);
|
||||
mContentHolder.setVisibility(View.VISIBLE);
|
||||
mContentHolder.setAlpha(1f);
|
||||
mContentHolder.removeAllViews();
|
||||
final View content = intruderView.apply(getContext(), mContentHolder);
|
||||
final View content = headsUp.contentView.apply(getContext(), mContentHolder);
|
||||
if (listener != null) {
|
||||
content.setOnClickListener(listener);
|
||||
|
||||
//content.setBackgroundResource(R.drawable.intruder_row_bg);
|
||||
Drawable bg = getResources().getDrawable(R.drawable.intruder_row_bg);
|
||||
|
||||
Drawable bg = getResources().getDrawable(R.drawable.heads_up_notification_row_bg);
|
||||
if (bg == null) {
|
||||
Log.e(TAG, String.format("Can't find background drawable id=0x%08x", R.drawable.intruder_row_bg));
|
||||
Log.e(TAG, String.format("Can't find background drawable id=0x%08x",
|
||||
R.drawable.heads_up_notification_row_bg));
|
||||
} else {
|
||||
content.setBackgroundDrawable(bg);
|
||||
}
|
||||
}
|
||||
mContentHolder.addView(content);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user