summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/drawable/intruder_row_bg.xml20
-rw-r--r--packages/SystemUI/res/drawable/intruder_window_bg.9.pngbin0 -> 272 bytes
-rw-r--r--packages/SystemUI/res/layout/intruder_alert.xml48
-rw-r--r--packages/SystemUI/res/values/colors.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java99
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java176
7 files changed, 292 insertions, 56 deletions
diff --git a/packages/SystemUI/res/drawable/intruder_row_bg.xml b/packages/SystemUI/res/drawable/intruder_row_bg.xml
new file mode 100644
index 0000000..1c7c9c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/intruder_row_bg.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<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" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/intruder_window_bg.9.png b/packages/SystemUI/res/drawable/intruder_window_bg.9.png
new file mode 100644
index 0000000..caad169
--- /dev/null
+++ b/packages/SystemUI/res/drawable/intruder_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/intruder_alert.xml b/packages/SystemUI/res/layout/intruder_alert.xml
index ba4a774..c4141ae 100644
--- a/packages/SystemUI/res/layout/intruder_alert.xml
+++ b/packages/SystemUI/res/layout/intruder_alert.xml
@@ -19,40 +19,22 @@
-->
<!-- android:background="@drawable/status_bar_closed_default_background" -->
-<FrameLayout
+<com.android.systemui.statusbar.policy.IntruderAlertView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="32dip"
+ android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
+ android:orientation="vertical"
>
-
- <LinearLayout
- android:id="@+id/intruder_alert_content"
+ <FrameLayout
+ android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:animationCache="false"
- android:orientation="horizontal"
- android:background="@drawable/alert_bar_background"
- android:clickable="true"
- android:focusable="true"
- android:descendantFocusability="afterDescendants"
- >
-
- <ImageView
- android:id="@+id/alertIcon"
- android:layout_width="25dip"
- android:layout_height="25dip"
- android:layout_marginLeft="6dip"
- android:layout_marginRight="8dip"
- />
- <TextView
- android:id="@+id/alertText"
- android:textAppearance="@style/TextAppearance.StatusBar.IntruderAlert"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- />
- </LinearLayout>
-</FrameLayout>
+ android:id="@+id/contentHolder"
+ android:background="@drawable/intruder_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>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 7f00c38..c8e3fad 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -30,4 +30,5 @@
<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>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 36d9316..3a06127 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -158,4 +158,8 @@ public abstract class BaseStatusBar extends SystemUI implements CommandQueue.Cal
}
return vetoButton;
}
+
+ public void dismissIntruder() {
+ // pass
+ }
}
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 9306127..85e0a8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -56,6 +56,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
@@ -77,6 +78,7 @@ import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
import com.android.systemui.recent.RecentTasksLoader;
import com.android.systemui.recent.RecentsPanelView;
import com.android.systemui.recent.TaskDescription;
@@ -86,6 +88,7 @@ import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.policy.DateView;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.IntruderAlertView;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NotificationRowLayout;
@@ -102,7 +105,7 @@ public class PhoneStatusBar extends BaseStatusBar {
public static final String ACTION_STATUSBAR_START
= "com.android.internal.policy.statusbar.START";
- private static final boolean ENABLE_INTRUDERS = false;
+ private static final boolean ENABLE_INTRUDERS = true;
static final int EXPANDED_LEAVE_ALONE = -10000;
static final int EXPANDED_FULL_OPEN = -10001;
@@ -117,7 +120,7 @@ public class PhoneStatusBar extends BaseStatusBar {
private static final int MSG_CLOSE_RECENTS_PANEL = 1021;
// will likely move to a resource or other tunable param at some point
- private static final int INTRUDER_ALERT_DECAY_MS = 10000;
+ private static final int INTRUDER_ALERT_DECAY_MS = 0; // disabled, was 10000;
private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
@@ -185,7 +188,7 @@ public class PhoneStatusBar extends BaseStatusBar {
DateView mDateView;
// for immersive activities
- private View mIntruderAlertView;
+ private IntruderAlertView mIntruderAlertView;
// on-screen navigation buttons
private NavigationBarView mNavigationBarView = null;
@@ -294,9 +297,9 @@ public class PhoneStatusBar extends BaseStatusBar {
}
mNotificationPanel = expanded.findViewById(R.id.notification_panel);
- mIntruderAlertView = View.inflate(context, R.layout.intruder_alert, null);
+ mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
mIntruderAlertView.setVisibility(View.GONE);
- mIntruderAlertView.setClickable(true);
+ mIntruderAlertView.setBar(this);
PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
R.layout.status_bar, null);
@@ -455,6 +458,7 @@ public class PhoneStatusBar extends BaseStatusBar {
toggleRecentApps();
}
};
+ private StatusBarNotification mCurrentlyIntrudingNotification;
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
@@ -510,7 +514,7 @@ public class PhoneStatusBar extends BaseStatusBar {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
- WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
+ WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
@@ -519,7 +523,7 @@ public class PhoneStatusBar extends BaseStatusBar {
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
- lp.y += height * 1.5; // FIXME
+ //lp.y += height * 1.5; // FIXME
lp.setTitle("IntruderAlert");
lp.packageName = mContext.getPackageName();
lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
@@ -562,30 +566,39 @@ public class PhoneStatusBar extends BaseStatusBar {
} catch (RemoteException ex) {
}
if (ENABLE_INTRUDERS && (
- (notification.score >= mIntruderInImmersiveMinScore)
- || (!immersive && (notification.score > mIntruderMinScore)))) {
+ // TODO(dsandler): Only if the screen is on
+ notification.notification.intruderView != null)) {
+// notification.notification.fullScreenIntent != null
+// || (notification.score >= mIntruderInImmersiveMinScore)
+// || (!immersive && (notification.score > mIntruderMinScore)))) {
Slog.d(TAG, "Presenting high-priority notification");
// special new transient ticker mode
// 1. Populate mIntruderAlertView
+
+ if (notification.notification.intruderView == null) {
+ Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
+ return;
+ }
- ImageView alertIcon = (ImageView) mIntruderAlertView.findViewById(R.id.alertIcon);
- TextView alertText = (TextView) mIntruderAlertView.findViewById(R.id.alertText);
- alertIcon.setImageDrawable(StatusBarIconView.getIcon(
- alertIcon.getContext(),
- iconView.getStatusBarIcon()));
- alertText.setText(notification.notification.tickerText);
+ // bind the click event to the content area
+ PendingIntent contentIntent = notification.notification.contentIntent;
+ final View.OnClickListener listener = (contentIntent != null)
+ ? new NotificationClicker(contentIntent,
+ notification.pkg, notification.tag, notification.id)
+ : null;
- View button = mIntruderAlertView.findViewById(R.id.intruder_alert_content);
- button.setOnClickListener(
- new NotificationClicker(notification.notification.contentIntent,
- notification.pkg, notification.tag, notification.id));
+ mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener);
+ mCurrentlyIntrudingNotification = notification;
+
// 2. Animate mIntruderAlertView in
mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
// 3. Set alarm to age the notification off (TODO)
mHandler.removeMessages(MSG_HIDE_INTRUDER);
- mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
+ if (INTRUDER_ALERT_DECAY_MS > 0) {
+ mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
+ }
} else if (notification.notification.fullScreenIntent != null) {
// not immersive & a full-screen alert should be shown
Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
@@ -596,8 +609,10 @@ public class PhoneStatusBar extends BaseStatusBar {
} else {
// usual case: status bar visible & not immersive
- // show the ticker
- tick(notification);
+ // show the ticker if there isn't an intruder too
+ if (mCurrentlyIntrudingNotification == null) {
+ tick(notification);
+ }
}
// Recalculate the position of the sliding windows and the titles.
@@ -708,11 +723,22 @@ public class PhoneStatusBar extends BaseStatusBar {
// Recalculate the position of the sliding windows and the titles.
setAreThereNotifications();
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+
+ // See if we need to update the intruder.
+ if (oldNotification == mCurrentlyIntrudingNotification) {
+ if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification);
+ // XXX: this is a hack for Alarms. The real implementation will need to *update*
+ // the intruder.
+ if (notification.notification.fullScreenIntent == null) { // TODO(dsandler): consistent logic with add()
+ if (DEBUG) Slog.d(TAG, "no longer intrudes!");
+ mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
+ }
+ }
}
public void removeNotification(IBinder key) {
- if (SPEW) Slog.d(TAG, "removeNotification key=" + key);
StatusBarNotification old = removeNotificationViews(key);
+ if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old);
if (old != null) {
// Cancel the ticker if it's still running
@@ -720,6 +746,10 @@ public class PhoneStatusBar extends BaseStatusBar {
// Recalculate the position of the sliding windows and the titles.
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+
+ if (old == mCurrentlyIntrudingNotification) {
+ mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
+ }
if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 && !mAnimating) {
animateCollapse();
@@ -1080,6 +1110,7 @@ public class PhoneStatusBar extends BaseStatusBar {
break;
case MSG_HIDE_INTRUDER:
setIntruderAlertVisibility(false);
+ mCurrentlyIntrudingNotification = null;
break;
case MSG_OPEN_RECENTS_PANEL:
if (DEBUG) Slog.d(TAG, "opening recents panel");
@@ -1576,6 +1607,12 @@ public class PhoneStatusBar extends BaseStatusBar {
}
public void onClick(View v) {
+ if (DEBUG) {
+ Slog.v(TAG, "NotificationClicker: intent=" + mIntent
+ + " pkg=" + mPkg
+ + " tag=" + mTag
+ + " id=" + mId);
+ }
try {
// The intent we are sending is for the application, which
// won't have permission to immediately start an activity after
@@ -2182,9 +2219,25 @@ public class PhoneStatusBar extends BaseStatusBar {
};
private void setIntruderAlertVisibility(boolean vis) {
+ if (DEBUG) {
+ Slog.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
+ }
mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
}
+ public void dismissIntruder() {
+ if (mCurrentlyIntrudingNotification == null) return;
+
+ try {
+ mBarService.onNotificationClear(
+ mCurrentlyIntrudingNotification.pkg,
+ mCurrentlyIntrudingNotification.tag,
+ mCurrentlyIntrudingNotification.id);
+ } catch (android.os.RemoteException ex) {
+ // oh well
+ }
+ }
+
/**
* Reload some of our resources when the configuration changes.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java
new file mode 100644
index 0000000..ee5c863
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.LayoutTransition;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+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;
+
+import java.util.HashMap;
+
+public class IntruderAlertView extends LinearLayout implements SwipeHelper.Callback {
+ private static final String TAG = "IntruderAlertView";
+ private static final boolean DEBUG = false;
+
+ Rect mTmpRect = new Rect();
+
+ private SwipeHelper mSwipeHelper;
+
+ BaseStatusBar mBar;
+ private ViewGroup mContentHolder;
+
+ private RemoteViews mIntruderRemoteViews;
+ private OnClickListener mOnClickListener;
+
+ public IntruderAlertView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public IntruderAlertView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ setOrientation(LinearLayout.VERTICAL);
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ float densityScale = getResources().getDisplayMetrics().density;
+ float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
+ mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+
+ mContentHolder = (ViewGroup) findViewById(R.id.contentHolder);
+ if (mIntruderRemoteViews != null) {
+ // whoops, we're on already!
+ applyIntruderContent(mIntruderRemoteViews, mOnClickListener);
+ }
+ }
+
+ public void setBar(BaseStatusBar bar) {
+ mBar = bar;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
+ return mSwipeHelper.onInterceptTouchEvent(ev) ||
+ super.onInterceptTouchEvent(ev);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ return mSwipeHelper.onTouchEvent(ev) ||
+ super.onTouchEvent(ev);
+ }
+
+ public boolean canChildBeDismissed(View v) {
+ return true;
+ }
+
+ public void onChildDismissed(View v) {
+ Slog.v(TAG, "User swiped intruder to dismiss");
+ mBar.dismissIntruder();
+ }
+
+ public void onBeginDrag(View v) {
+ }
+
+ public void onDragCancelled(View v) {
+ mContentHolder.setAlpha(1f); // sometimes this isn't quite reset
+ }
+
+ public View getChildAtPosition(MotionEvent ev) {
+ return mContentHolder;
+ }
+
+ public View getChildContentView(View v) {
+ return v;
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ float densityScale = getResources().getDisplayMetrics().density;
+ mSwipeHelper.setDensityScale(densityScale);
+ float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
+ mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
+ }
+
+ @Override
+ public void onDraw(android.graphics.Canvas c) {
+ super.onDraw(c);
+ if (DEBUG) {
+ //Slog.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
+ // + getMeasuredHeight() + "px");
+ c.save();
+ c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6,
+ android.graphics.Region.Op.DIFFERENCE);
+ c.drawColor(0xFFcc00cc);
+ c.restore();
+ }
+ }
+
+ public void applyIntruderContent(RemoteViews intruderView, OnClickListener listener) {
+ if (DEBUG) {
+ Slog.v(TAG, "applyIntruderContent: view=" + intruderView + " listener=" + listener);
+ }
+ mIntruderRemoteViews = intruderView;
+ mOnClickListener = listener;
+ if (mContentHolder == null) {
+ // too soon!
+ return;
+ }
+ mContentHolder.setX(0);
+ mContentHolder.setVisibility(View.VISIBLE);
+ mContentHolder.setAlpha(1f);
+ mContentHolder.removeAllViews();
+ final View content = intruderView.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);
+ if (bg == null) {
+ Log.e(TAG, String.format("Can't find background drawable id=0x%08x", R.drawable.intruder_row_bg));
+ } else {
+ content.setBackgroundDrawable(bg);
+ }
+ }
+ mContentHolder.addView(content);
+
+ }
+} \ No newline at end of file