diff --git a/core/res/res/drawable/notification_quantum_bg.xml b/core/res/res/drawable/notification_quantum_bg.xml
index 608115e631e9a..300a565ba68eb 100644
--- a/core/res/res/drawable/notification_quantum_bg.xml
+++ b/core/res/res/drawable/notification_quantum_bg.xml
@@ -16,6 +16,16 @@
-->
-
-
+ -
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/core/res/res/drawable/notification_quantum_background.xml b/core/res/res/drawable/notification_quantum_bg_dim.xml
similarity index 67%
rename from core/res/res/drawable/notification_quantum_background.xml
rename to core/res/res/drawable/notification_quantum_bg_dim.xml
index 7b508a94dcb13..11b6e1b5d534d 100644
--- a/core/res/res/drawable/notification_quantum_background.xml
+++ b/core/res/res/drawable/notification_quantum_bg_dim.xml
@@ -15,7 +15,14 @@
~ limitations under the License
-->
-
-
-
-
\ No newline at end of file
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/res/res/layout/notification_template_quantum_base.xml b/core/res/res/layout/notification_template_quantum_base.xml
index 8863cfa9341d7..8f3019d829f0e 100644
--- a/core/res/res/layout/notification_template_quantum_base.xml
+++ b/core/res/res/layout/notification_template_quantum_base.xml
@@ -17,7 +17,6 @@
+
+
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index e74e5684710d4..d61d8b9cb8919 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -32,6 +32,7 @@
android:layout_marginTop="@dimen/notification_divider_height"
android:focusable="true"
android:clickable="true"
+ android:background="@*android:drawable/notification_quantum_bg"
>
0 && version < Build.VERSION_CODES.GINGERBREAD) {
content.setBackgroundResource(R.drawable.notification_row_legacy_bg);
- } else {
- content.setBackgroundResource(com.android.internal.R.drawable.notification_bg);
}
}
}
@@ -1004,7 +1002,7 @@ public abstract class BaseStatusBar extends SystemUI implements
// Remove the expanded view.
ViewGroup rowParent = (ViewGroup)entry.row.getParent();
if (rowParent != null) rowParent.removeView(entry.row);
- updateExpansionStates();
+ updateRowStates();
updateNotificationIcons();
return entry.notification;
@@ -1048,7 +1046,7 @@ public abstract class BaseStatusBar extends SystemUI implements
Log.d(TAG, "addNotificationViews: added at " + pos);
}
updateInterceptedState(entry);
- updateExpansionStates();
+ updateRowStates();
updateNotificationIcons();
}
@@ -1056,7 +1054,10 @@ public abstract class BaseStatusBar extends SystemUI implements
addNotificationViews(createNotificationViews(key, notification));
}
- protected void updateExpansionStates() {
+ /**
+ * Updates expanded, dimmed and locked states of notification rows.
+ */
+ protected void updateRowStates() {
int n = mNotificationData.size();
for (int i = 0; i < n; i++) {
NotificationData.Entry entry = mNotificationData.get(i);
@@ -1068,6 +1069,8 @@ public abstract class BaseStatusBar extends SystemUI implements
entry.row.setExpanded(top || entry.row.isUserExpanded());
}
}
+ entry.row.setDimmed(mOnKeyguard);
+ entry.row.setLocked(mOnKeyguard);
}
}
@@ -1222,7 +1225,7 @@ public abstract class BaseStatusBar extends SystemUI implements
handleNotificationError(key, notification, "Couldn't update icon: " + ic);
return;
}
- updateExpansionStates();
+ updateRowStates();
}
catch (RuntimeException e) {
// It failed to add cleanly. Log, and remove the view from the panel.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index b3d8688d4b42f..c9ca55b4ff668 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -36,10 +36,18 @@ public class ExpandableNotificationRow extends FrameLayout {
/** are we showing the "public" version */
private boolean mShowingPublic;
+ private LatestItemView mLatestItemView;
+
public ExpandableNotificationRow(Context context, AttributeSet attrs) {
super(context, attrs);
}
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mLatestItemView = (LatestItemView) findViewById(R.id.container);
+ }
+
public int getRowHeight() {
return mRowHeight;
}
@@ -93,4 +101,19 @@ public class ExpandableNotificationRow extends FrameLayout {
publicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
findViewById(R.id.expanded).setVisibility(show ? View.GONE : View.VISIBLE);
}
+
+ /**
+ * Sets the notification as dimmed, meaning that it will appear in a more gray variant.
+ */
+ public void setDimmed(boolean dimmed) {
+ mLatestItemView.setDimmed(dimmed);
+ }
+
+ /**
+ * Sets the notification as locked. In the locked state, the first tap will produce a quantum
+ * ripple to make the notification brighter and only the second tap will cause a click.
+ */
+ public void setLocked(boolean locked) {
+ mLatestItemView.setLocked(locked);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java b/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
index 6419777566472..ad9028dc860e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
@@ -17,16 +17,44 @@
package com.android.systemui.statusbar;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
public class LatestItemView extends FrameLayout {
+
+ private static final long DOUBLETAP_TIMEOUT_MS = 1000;
+
+ private boolean mDimmed;
+ private boolean mLocked;
+
+ /**
+ * Flag to indicate that the notification has been touched once and the second touch will
+ * click it.
+ */
+ private boolean mActivated;
+
+ private float mDownX;
+ private float mDownY;
+ private final float mTouchSlop;
+ private boolean mHotspotActive;
+
public LatestItemView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
+ private final Runnable mTapTimeoutRunnable = new Runnable() {
+ @Override
+ public void run() {
+ makeInactive();
+ }
+ };
+
@Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
@@ -45,4 +73,94 @@ public class LatestItemView extends FrameLayout {
}
return false;
}
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mLocked) {
+ return handleTouchEventLocked(event);
+ } else {
+ return super.onTouchEvent(event);
+ }
+ }
+
+ private boolean handleTouchEventLocked(MotionEvent event) {
+ int action = event.getActionMasked();
+ Drawable background = getBackground();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ mDownX = event.getX();
+ mDownY = event.getY();
+ if (!mActivated) {
+ background.setHotspot(0, event.getX(), event.getY());
+ mHotspotActive = true;
+ }
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (!isWithinTouchSlop(event)) {
+ makeInactive();
+ return false;
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (isWithinTouchSlop(event)) {
+ if (!mActivated) {
+ mActivated = true;
+ postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
+ } else {
+ performClick();
+ makeInactive();
+ }
+ } else {
+ makeInactive();
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ makeInactive();
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * Cancels the hotspot and makes the notification inactive.
+ */
+ private void makeInactive() {
+ if (mHotspotActive) {
+ // Make sure that we clear the hotspot from the center.
+ getBackground().setHotspot(0, getWidth()/2, getHeight()/2);
+ getBackground().removeHotspot(0);
+ mHotspotActive = false;
+ }
+ mActivated = false;
+ removeCallbacks(mTapTimeoutRunnable);
+ }
+
+ private boolean isWithinTouchSlop(MotionEvent event) {
+ return Math.abs(event.getX() - mDownX) < mTouchSlop
+ && Math.abs(event.getY() - mDownY) < mTouchSlop;
+ }
+
+ /**
+ * Sets the notification as dimmed, meaning that it will appear in a more gray variant.
+ */
+ public void setDimmed(boolean dimmed) {
+ if (mDimmed != dimmed) {
+ mDimmed = dimmed;
+ if (dimmed) {
+ setBackgroundResource(com.android.internal.R.drawable.notification_quantum_bg_dim);
+ } else {
+ setBackgroundResource(com.android.internal.R.drawable.notification_quantum_bg);
+ }
+ }
+ }
+
+ /**
+ * Sets the notification as locked. In the locked state, the first tap will produce a quantum
+ * ripple to make the notification brighter and only the second tap will cause a click.
+ */
+ public void setLocked(boolean locked) {
+ mLocked = locked;
+ }
}
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 9b025275ea57b..e34911dcbdeeb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2804,9 +2804,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
mKeyguardSettingsFlipButton.setVisibility(View.VISIBLE);
mKeyguardSettingsFlipButton.findViewById(R.id.settings_button).setVisibility(View.VISIBLE);
- mStackScroller.setAlpha(0.8f);
- mStackScroller.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- updateExpansionStates();
+ updateRowStates();
}
public void hideKeyguard() {
@@ -2815,9 +2813,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
mKeyguardStatusView.setVisibility(View.GONE);
mNotificationPanelHeader.setVisibility(View.VISIBLE);
mKeyguardSettingsFlipButton.setVisibility(View.GONE);
- mStackScroller.setAlpha(1f);
- mStackScroller.setLayerType(View.LAYER_TYPE_NONE, null);
- updateExpansionStates();
+ updateRowStates();
}
public void userActivity() {