diff options
Diffstat (limited to 'packages/SystemUI/src')
37 files changed, 499 insertions, 808 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index 0fb0f8b..192ba57 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -17,13 +17,16 @@ package com.android.systemui.power; import android.content.BroadcastReceiver; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.database.ContentObserver; import android.os.BatteryManager; import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; +import android.os.UserHandle; import android.provider.Settings; import android.util.Slog; @@ -54,17 +57,22 @@ public class PowerUI extends SystemUI { public void start() { - mLowBatteryAlertCloseLevel = mContext.getResources().getInteger( - com.android.internal.R.integer.config_lowBatteryCloseWarningLevel); - mLowBatteryReminderLevels[0] = mContext.getResources().getInteger( - com.android.internal.R.integer.config_lowBatteryWarningLevel); - mLowBatteryReminderLevels[1] = mContext.getResources().getInteger( - com.android.internal.R.integer.config_criticalBatteryWarningLevel); - final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mScreenOffTime = pm.isScreenOn() ? -1 : SystemClock.elapsedRealtime(); mWarnings = new PowerDialogWarnings(mContext); + ContentObserver obs = new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange) { + updateBatteryWarningLevels(); + } + }; + final ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), + false, obs, UserHandle.USER_ALL); + updateBatteryWarningLevels(); + // Register for Intent broadcasts for... IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); @@ -73,6 +81,29 @@ public class PowerUI extends SystemUI { mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); } + void updateBatteryWarningLevels() { + int critLevel = mContext.getResources().getInteger( + com.android.internal.R.integer.config_criticalBatteryWarningLevel); + + final ContentResolver resolver = mContext.getContentResolver(); + int defWarnLevel = mContext.getResources().getInteger( + com.android.internal.R.integer.config_lowBatteryWarningLevel); + int warnLevel = Settings.Global.getInt(resolver, + Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel); + if (warnLevel == 0) { + warnLevel = defWarnLevel; + } + if (warnLevel < critLevel) { + warnLevel = critLevel; + } + + mLowBatteryReminderLevels[0] = warnLevel; + mLowBatteryReminderLevels[1] = critLevel; + mLowBatteryAlertCloseLevel = mLowBatteryReminderLevels[0] + + mContext.getResources().getInteger( + com.android.internal.R.integer.config_lowBatteryCloseWarningBump); + } + /** * Buckets the battery level. * @@ -87,7 +118,7 @@ public class PowerUI extends SystemUI { if (level >= mLowBatteryAlertCloseLevel) { return 1; } - if (level >= mLowBatteryReminderLevels[0]) { + if (level > mLowBatteryReminderLevels[0]) { return 0; } final int N = mLowBatteryReminderLevels.length; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java index c76ee8c..786cd9e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java @@ -287,6 +287,7 @@ public abstract class QSTile<TState extends State> implements Listenable { public boolean activityIn; public boolean activityOut; public int overlayIconId; + public boolean filter; @Override public boolean copyTo(State other) { @@ -300,6 +301,7 @@ public abstract class QSTile<TState extends State> implements Listenable { o.activityIn = activityIn; o.activityOut = activityOut; o.overlayIconId = overlayIconId; + o.filter = filter; return super.copyTo(other) || changed; } @@ -311,6 +313,7 @@ public abstract class QSTile<TState extends State> implements Listenable { rt.insert(rt.length() - 1, ",activityIn=" + activityIn); rt.insert(rt.length() - 1, ",activityOut=" + activityOut); rt.insert(rt.length() - 1, ",overlayIconId=" + overlayIconId); + rt.insert(rt.length() - 1, ",filter=" + filter); return rt; } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java index 901cc10..d5fe033 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java @@ -93,12 +93,12 @@ public final class SignalTileView extends QSTileView { final SignalState s = (SignalState) state; mSignal.setImageDrawable(null); // force refresh mSignal.setImageResource(s.iconId); - mSignal.setColorFilter(FILTER); + mSignal.setColorFilter(s.filter ? FILTER : null); if (s.overlayIconId > 0) { mOverlay.setVisibility(VISIBLE); mOverlay.setImageDrawable(null); // force refresh mOverlay.setImageResource(s.overlayIconId); - mOverlay.setColorFilter(FILTER); + mOverlay.setColorFilter(s.filter ? FILTER : null); } else { mOverlay.setVisibility(GONE); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 182a0ce..6d91d33 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -72,12 +72,15 @@ public class CellularTile extends QSTile<QSTile.SignalState> { if (cb == null) return; final Resources r = mContext.getResources(); - state.iconId = cb.enabled && (cb.mobileSignalIconId > 0) + state.iconId = cb.noSim + ? R.drawable.stat_sys_no_sim + : cb.enabled && (cb.mobileSignalIconId > 0) ? cb.mobileSignalIconId : R.drawable.ic_qs_signal_no_signal; state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiEnabled ? cb.dataTypeIconId : 0; + state.filter = state.iconId != R.drawable.stat_sys_no_sim; state.activityIn = cb.enabled && cb.activityIn; state.activityOut = cb.enabled && cb.activityOut; @@ -117,6 +120,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> { boolean activityIn; boolean activityOut; String enabledDesc; + boolean noSim; } private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() { @@ -134,7 +138,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> { int mobileSignalIconId, String mobileSignalContentDescriptionId, int dataTypeIconId, boolean activityIn, boolean activityOut, - String dataTypeContentDescriptionId, String description) { + String dataTypeContentDescriptionId, String description, boolean noSim) { final CallbackInfo info = new CallbackInfo(); // TODO pool? info.enabled = enabled; info.wifiEnabled = mWifiEnabled; @@ -145,6 +149,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> { info.activityIn = activityIn; info.activityOut = activityOut; info.enabledDesc = description; + info.noSim = noSim; refreshState(info); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index 5301362..7c2c7c3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -71,6 +71,6 @@ public class ColorInversionTile extends QSTile<QSTile.BooleanState> { state.visible = mVisible; state.value = enabled; state.label = mContext.getString(R.string.quick_settings_inversion_label); - state.iconId = R.drawable.ic_qs_color_inversion; + state.iconId = enabled ? R.drawable.ic_qs_inversion_on : R.drawable.ic_qs_inversion_off; } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index db9b054..04f1eb5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -16,9 +16,6 @@ package com.android.systemui.qs.tiles; -import android.content.res.Resources; -import android.graphics.drawable.AnimationDrawable; - import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.policy.LocationController; @@ -63,28 +60,15 @@ public class LocationTile extends QSTile<QSTile.BooleanState> { protected void handleUpdateState(BooleanState state, Object arg) { final boolean locationEnabled = mController.isLocationEnabled(); state.visible = true; - if (state.value != locationEnabled) { - state.value = locationEnabled; - final Resources res = mContext.getResources(); - final AnimationDrawable d = (AnimationDrawable) res.getDrawable(locationEnabled - ? R.drawable.ic_qs_location_on - : R.drawable.ic_qs_location_off); - state.icon = d; - mUiHandler.post(new Runnable() { - @Override - public void run() { - d.start(); - } - }); - } + state.value = locationEnabled; if (locationEnabled) { - if (state.icon == null) state.iconId = R.drawable.ic_qs_location_01; + state.iconId = R.drawable.ic_qs_location_on; state.label = mContext.getString(R.string.quick_settings_location_label); state.contentDescription = mContext.getString( R.string.accessibility_quick_settings_location, mContext.getString(R.string.accessibility_desc_on)); } else { - if (state.icon == null) state.iconId = R.drawable.ic_qs_location_11; + state.iconId = R.drawable.ic_qs_location_off; state.label = mContext.getString(R.string.quick_settings_location_label); state.contentDescription = mContext.getString( R.string.accessibility_quick_settings_location, diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 6b73002..a236497 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -87,6 +87,7 @@ public class WifiTile extends QSTile<QSTile.SignalState> { state.connected = wifiConnected; state.activityIn = cb.enabled && cb.activityIn; state.activityOut = cb.enabled && cb.activityOut; + state.filter = true; final String signalContentDescription; final Resources r = mContext.getResources(); if (wifiConnected) { @@ -159,7 +160,7 @@ public class WifiTile extends QSTile<QSTile.SignalState> { int mobileSignalIconId, String mobileSignalContentDescriptionId, int dataTypeIconId, boolean activityIn, boolean activityOut, - String dataTypeContentDescriptionId, String description) { + String dataTypeContentDescriptionId, String description, boolean noSim) { // noop } diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java index 76e88a5..147ff62 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java @@ -106,7 +106,7 @@ public class Constants { // The height of the peek space relative to the stack height public static final float StackPeekHeightPct = 0.1f; // The min scale of the last card in the peek area - public static final float StackPeekMinScale = 0.9f; + public static final float StackPeekMinScale = 0.8f; // The number of cards we see in the peek space public static final int StackPeekNumCards = 3; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 8680786..96344d5 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -41,6 +41,8 @@ import com.android.systemui.recents.model.SpaceNode; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.views.RecentsView; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Set; @@ -79,6 +81,19 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView boolean mVisible; boolean mTaskLaunched; + private static Method sPropertyMethod; + static { + try { + Class<?> c = Class.forName("android.view.GLES20Canvas"); + sPropertyMethod = c.getDeclaredMethod("setProperty", String.class, String.class); + if (!sPropertyMethod.isAccessible()) sPropertyMethod.setAccessible(true); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + // Broadcast receiver to handle messages from our RecentsService BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() { @Override @@ -139,21 +154,12 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView // Add the default no-recents layout if (stacks.size() == 1 && stacks.get(0).getTaskCount() == 0) { mEmptyView.setVisibility(View.VISIBLE); - - // Dim the background even more - WindowManager.LayoutParams wlp = getWindow().getAttributes(); - wlp.dimAmount = Constants.Values.Window.DarkBackgroundDim; - getWindow().setAttributes(wlp); - getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); } else { mEmptyView.setVisibility(View.GONE); - - // Un-dim the background - WindowManager.LayoutParams wlp = getWindow().getAttributes(); - wlp.dimAmount = 0f; - getWindow().setAttributes(wlp); - getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); } + + // Dim the background + mRecentsView.setBackgroundColor(0x80000000); } /** Attempts to allocate and bind the search bar app widget */ @@ -277,6 +283,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView LayoutInflater inflater = LayoutInflater.from(this); mEmptyView = inflater.inflate(R.layout.recents_empty, mContainerView, false); mNavBarScrimView = inflater.inflate(R.layout.recents_nav_bar_scrim, mContainerView, false); + mNavBarScrimView.setLayoutParams(new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM)); mContainerView = new FrameLayout(this); mContainerView.addView(mRecentsView); @@ -296,6 +305,16 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView if (savedInstanceState != null) { onConfigurationChange(); } + + // XXX: Update the shadows + try { + sPropertyMethod.invoke(null, "ambientShadowStrength", String.valueOf(35f)); + sPropertyMethod.invoke(null, "ambientRatio", String.valueOf(0.5f)); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } } void onConfigurationChange() { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 5830e37..8d9f8be 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -156,10 +156,12 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal float boundedT = Math.max(t, -(numPeekCards + 1)); // Set the scale relative to its position + int numFrontScaledCards = 3; float minScale = Constants.Values.TaskStackView.StackPeekMinScale; float scaleRange = 1f - minScale; - float scaleInc = scaleRange / numPeekCards; - float scale = Math.max(minScale, Math.min(1f, 1f + (boundedT * scaleInc))); + float scaleInc = scaleRange / (numPeekCards + numFrontScaledCards); + float scale = Math.max(minScale, Math.min(1f, minScale + + ((boundedT + (numPeekCards + 1)) * scaleInc))); float scaleYOffset = ((1f - scale) * mTaskRect.height()) / 2; transform.scale = scale; @@ -171,6 +173,12 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal transform.translationY = (int) (boundedT * overlapHeight - scaleYOffset); } + // Set the z translation + RecentsConfiguration config = RecentsConfiguration.getInstance(); + int minZ = config.taskViewTranslationZMinPx; + int incZ = config.taskViewTranslationZIncrementPx; + transform.translationZ = (int) Math.max(minZ, minZ + ((boundedT + numPeekCards) * incZ)); + // Set the alphas transform.dismissAlpha = Math.max(-1f, Math.min(0f, t + 1)) + 1f; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 632c816..5df5e4d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -142,8 +142,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On void updateViewPropertiesToTaskTransform(TaskViewTransform animateFromTransform, TaskViewTransform toTransform, int duration) { RecentsConfiguration config = RecentsConfiguration.getInstance(); - int minZ = config.taskViewTranslationZMinPx; - int incZ = config.taskViewTranslationZIncrementPx; // Update the bar view mBarView.updateViewPropertiesToTaskTransform(animateFromTransform, toTransform, duration); @@ -153,14 +151,14 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On if (animateFromTransform != null) { setTranslationY(animateFromTransform.translationY); if (Constants.DebugFlags.App.EnableShadows) { - setTranslationZ(Math.max(minZ, minZ + (animateFromTransform.t * incZ))); + setTranslationZ(animateFromTransform.translationZ); } setScaleX(animateFromTransform.scale); setScaleY(animateFromTransform.scale); setAlpha(animateFromTransform.alpha); } if (Constants.DebugFlags.App.EnableShadows) { - animate().translationZ(Math.max(minZ, minZ + (toTransform.t * incZ))); + animate().translationZ(toTransform.translationZ); } animate().translationY(toTransform.translationY) .scaleX(toTransform.scale) @@ -179,7 +177,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On } else { setTranslationY(toTransform.translationY); if (Constants.DebugFlags.App.EnableShadows) { - setTranslationZ(Math.max(minZ, minZ + (toTransform.t * incZ))); + setTranslationZ(toTransform.translationZ); } setScaleX(toTransform.scale); setScaleY(toTransform.scale); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java index e6391a8..3c3ebd7 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java @@ -22,6 +22,7 @@ import android.graphics.Rect; /* The transform state for a task view */ public class TaskViewTransform { public int translationY = 0; + public int translationZ = 0; public float scale = 1f; public float alpha = 1f; public float dismissAlpha = 1f; @@ -35,6 +36,7 @@ public class TaskViewTransform { public TaskViewTransform(TaskViewTransform o) { translationY = o.translationY; + translationZ = o.translationZ; scale = o.scale; alpha = o.alpha; dismissAlpha = o.dismissAlpha; diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index a770f58..80e85f9 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -34,6 +34,7 @@ import java.util.ArrayList; public class BrightnessController implements ToggleSlider.Listener { private static final String TAG = "StatusBar.BrightnessController"; + private static final boolean SHOW_AUTOMATIC_ICON = false; /** * {@link android.provider.Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ} uses the range [-1, 1]. @@ -232,7 +233,7 @@ public class BrightnessController implements ToggleSlider.Listener { private void updateIcon(boolean automatic) { if (mIcon != null) { - mIcon.setImageResource(automatic ? + mIcon.setImageResource(automatic && SHOW_AUTOMATIC_ICON ? com.android.systemui.R.drawable.ic_qs_brightness_auto_on : com.android.systemui.R.drawable.ic_qs_brightness_auto_off); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index b91e129..8d19f50 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -158,7 +158,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private final Runnable mTapTimeoutRunnable = new Runnable() { @Override public void run() { - makeInactive(); + makeInactive(true /* animate */); } }; @@ -183,7 +183,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView break; case MotionEvent.ACTION_MOVE: if (!isWithinTouchSlop(event)) { - makeInactive(); + makeInactive(true /* animate */); return false; } break; @@ -193,14 +193,17 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView makeActive(); postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS); } else { - performClick(); + boolean performed = performClick(); + if (performed) { + removeCallbacks(mTapTimeoutRunnable); + } } } else { - makeInactive(); + makeInactive(true /* animate */); } break; case MotionEvent.ACTION_CANCEL: - makeInactive(); + makeInactive(true /* animate */); break; default: break; @@ -257,10 +260,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView /** * Cancels the hotspot and makes the notification inactive. */ - private void makeInactive() { + public void makeInactive(boolean animate) { if (mActivated) { if (mDimmed) { - startActivateAnimation(true /* reverse */); + if (animate) { + startActivateAnimation(true /* reverse */); + } else { + mBackgroundNormal.setVisibility(View.INVISIBLE); + } } mActivated = false; } @@ -351,6 +358,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundDimmed.setVisibility(View.INVISIBLE); mBackgroundNormal.setVisibility(View.VISIBLE); mBackgroundNormal.setAlpha(1f); + removeCallbacks(mTapTimeoutRunnable); } } @@ -581,7 +589,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } public interface OnActivatedListener { - void onActivated(View view); - void onActivationReset(View view); + void onActivated(ActivatableNotificationView view); + void onActivationReset(ActivatableNotificationView view); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index a7af998..5a9fe91 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -48,7 +48,7 @@ import android.provider.Settings; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.service.notification.NotificationListenerService; -import android.service.notification.NotificationListenerService.Ranking; +import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.util.Log; @@ -80,11 +80,10 @@ import com.android.systemui.SearchPanelView; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.phone.KeyguardTouchDelegate; +import com.android.systemui.statusbar.policy.HeadsUpNotificationView; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.Locale; import static com.android.keyguard.KeyguardHostView.OnDismissAction; @@ -106,6 +105,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected static final int MSG_SHOW_HEADS_UP = 1026; protected static final int MSG_HIDE_HEADS_UP = 1027; protected static final int MSG_ESCALATE_HEADS_UP = 1028; + protected static final int MSG_DECAY_HEADS_UP = 1029; protected static final boolean ENABLE_HEADS_UP = true; // scores above this threshold should be displayed in heads up mode. @@ -129,7 +129,9 @@ public abstract class BaseStatusBar extends SystemUI implements protected NotificationData mNotificationData = new NotificationData(); protected NotificationStackScrollLayout mStackScroller; - protected NotificationData.Entry mInterruptingNotificationEntry; + // for heads up notifications + protected HeadsUpNotificationView mHeadsUpNotificationView; + protected int mHeadsUpNotificationDecay; protected long mInterruptingNotificationTime; // used to notify status bar for suppressing notification LED @@ -291,7 +293,7 @@ public abstract class BaseStatusBar extends SystemUI implements public void onListenerConnected() { if (DEBUG) Log.d(TAG, "onListenerConnected"); final StatusBarNotification[] notifications = getActiveNotifications(); - final Ranking currentRanking = getCurrentRanking(); + final RankingMap currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { @@ -303,41 +305,40 @@ public abstract class BaseStatusBar extends SystemUI implements } @Override - public void onNotificationPosted(final StatusBarNotification sbn) { + public void onNotificationPosted(final StatusBarNotification sbn, + final RankingMap rankingMap) { if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn); - final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { if (mNotificationData.findByKey(sbn.getKey()) != null) { - updateNotificationInternal(sbn, currentRanking); + updateNotificationInternal(sbn, rankingMap); } else { - addNotificationInternal(sbn, currentRanking); + addNotificationInternal(sbn, rankingMap); } } }); } @Override - public void onNotificationRemoved(final StatusBarNotification sbn) { + public void onNotificationRemoved(final StatusBarNotification sbn, + final RankingMap rankingMap) { if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn); - final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { - removeNotificationInternal(sbn.getKey(), currentRanking); + removeNotificationInternal(sbn.getKey(), rankingMap); } }); } @Override - public void onNotificationRankingUpdate() { + public void onNotificationRankingUpdate(final RankingMap rankingMap) { if (DEBUG) Log.d(TAG, "onRankingUpdate"); - final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { - updateRankingInternal(currentRanking); + updateRankingInternal(rankingMap); } }); } @@ -505,8 +506,8 @@ public abstract class BaseStatusBar extends SystemUI implements protected View updateNotificationVetoButton(View row, StatusBarNotification n) { View vetoButton = row.findViewById(R.id.veto); - if (n.isClearable() || (mInterruptingNotificationEntry != null - && mInterruptingNotificationEntry.row == row)) { + if (n.isClearable() || (mHeadsUpNotificationView.getEntry() != null + && mHeadsUpNotificationView.getEntry().row == row)) { final String _pkg = n.getPackageName(); final String _tag = n.getTag(); final int _id = n.getId(); @@ -545,12 +546,11 @@ public abstract class BaseStatusBar extends SystemUI implements if (entry.expanded.getId() != com.android.internal.R.id.status_bar_latest_event_content) { // Using custom RemoteViews - if (version > 0 && version < Build.VERSION_CODES.GINGERBREAD) { - entry.row.setBackgroundResource(R.drawable.notification_row_legacy_bg); - } else if (version < Build.VERSION_CODES.L) { + if (version >= Build.VERSION_CODES.GINGERBREAD && version < Build.VERSION_CODES.L) { entry.row.setBackgroundResourceIds( com.android.internal.R.drawable.notification_bg, com.android.internal.R.drawable.notification_bg_dim); + entry.legacy = true; } } else { // Using platform templates @@ -766,6 +766,12 @@ public abstract class BaseStatusBar extends SystemUI implements public abstract void resetHeadsUpDecayTimer(); + public abstract void scheduleHeadsUpOpen(); + + public abstract void scheduleHeadsUpClose(); + + public abstract void scheduleHeadsUpEscalation(); + /** * Save the current "public" (locked and secure) state of the lockscreen. */ @@ -797,6 +803,18 @@ public abstract class BaseStatusBar extends SystemUI implements return mUsersAllowingPrivateNotifications.get(userHandle); } + public void onNotificationClear(StatusBarNotification notification) { + try { + mBarService.onNotificationClear( + notification.getPackageName(), + notification.getTag(), + notification.getId(), + notification.getUserId()); + } catch (android.os.RemoteException ex) { + // oh well + } + } + protected class H extends Handler { public void handleMessage(Message m) { Intent intent; @@ -1026,6 +1044,7 @@ public abstract class BaseStatusBar extends SystemUI implements com.android.internal.R.id.text); text.setText("Unlock your device to see this notification."); + entry.autoRedacted = true; // TODO: fill out "time" as well } @@ -1101,7 +1120,7 @@ public abstract class BaseStatusBar extends SystemUI implements try { if (mIsHeadsUp) { - mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); + mHeadsUpNotificationView.clear(); } mBarService.onNotificationClick(mNotificationKey); } catch (RemoteException ex) { @@ -1157,7 +1176,7 @@ public abstract class BaseStatusBar extends SystemUI implements } } - protected StatusBarNotification removeNotificationViews(String key, Ranking ranking) { + protected StatusBarNotification removeNotificationViews(String key, RankingMap ranking) { NotificationData.Entry entry = mNotificationData.remove(key, ranking); if (entry == null) { Log.w(TAG, "removeNotification for unknown key: " + key); @@ -1197,7 +1216,7 @@ public abstract class BaseStatusBar extends SystemUI implements return entry; } - protected void addNotificationViews(Entry entry, Ranking ranking) { + protected void addNotificationViews(Entry entry, RankingMap ranking) { if (entry == null) { return; } @@ -1206,7 +1225,7 @@ public abstract class BaseStatusBar extends SystemUI implements updateNotifications(); } - private void addNotificationViews(StatusBarNotification notification, Ranking ranking) { + private void addNotificationViews(StatusBarNotification notification, RankingMap ranking) { addNotificationViews(createNotificationViews(notification), ranking); } @@ -1292,9 +1311,9 @@ public abstract class BaseStatusBar extends SystemUI implements } public abstract void addNotificationInternal(StatusBarNotification notification, - Ranking ranking); + RankingMap ranking); - protected abstract void updateRankingInternal(Ranking ranking); + protected abstract void updateRankingInternal(RankingMap ranking); @Override public void removeNotification(String key) { @@ -1303,7 +1322,7 @@ public abstract class BaseStatusBar extends SystemUI implements } } - public abstract void removeNotificationInternal(String key, Ranking ranking); + public abstract void removeNotificationInternal(String key, RankingMap ranking); public void updateNotification(StatusBarNotification notification) { if (!USE_NOTIFICATION_LISTENER) { @@ -1311,7 +1330,7 @@ public abstract class BaseStatusBar extends SystemUI implements } } - public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) { + public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) { if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")"); final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey()); @@ -1394,15 +1413,15 @@ public abstract class BaseStatusBar extends SystemUI implements try { updateNotificationViews(oldEntry, notification); - if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null - && oldNotification == mInterruptingNotificationEntry.notification) { + if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null + && oldNotification == mHeadsUpNotificationView.getEntry().notification) { if (!shouldInterrupt(notification)) { if (DEBUG) Log.d(TAG, "no longer interrupts!"); - mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); + scheduleHeadsUpClose(); } else { if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification); - mInterruptingNotificationEntry.notification = notification; - updateHeadsUpViews(mInterruptingNotificationEntry, notification); + mHeadsUpNotificationView.getEntry().notification = notification; + updateHeadsUpViews(mHeadsUpNotificationView.getEntry(), notification); } } @@ -1511,8 +1530,8 @@ public abstract class BaseStatusBar extends SystemUI implements } protected void notifyHeadsUpScreenOn(boolean screenOn) { - if (!screenOn && mInterruptingNotificationEntry != null) { - mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP); + if (!screenOn) { + scheduleHeadsUpEscalation(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 84005d1..5bad602 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -209,7 +209,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { } public int getMaxExpandHeight() { - return mMaxExpandHeight; + return mShowingPublic ? mRowMinHeight : mMaxExpandHeight; } /** @@ -221,30 +221,35 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { @Override public boolean isContentExpandable() { - return mPrivateLayout.isContentExpandable(); + NotificationContentView showingLayout = getShowingLayout(); + return showingLayout.isContentExpandable(); } @Override public void setActualHeight(int height, boolean notifyListeners) { mPrivateLayout.setActualHeight(height); + mPublicLayout.setActualHeight(height); invalidate(); super.setActualHeight(height, notifyListeners); } @Override public int getMaxHeight() { - return mPrivateLayout.getMaxHeight(); + NotificationContentView showingLayout = getShowingLayout(); + return showingLayout.getMaxHeight(); } @Override public int getMinHeight() { - return mPrivateLayout.getMinHeight(); + NotificationContentView showingLayout = getShowingLayout(); + return showingLayout.getMinHeight(); } @Override public void setClipTopAmount(int clipTopAmount) { super.setClipTopAmount(clipTopAmount); mPrivateLayout.setClipTopAmount(clipTopAmount); + mPublicLayout.setClipTopAmount(clipTopAmount); } public boolean isBelowSpeedBump() { @@ -256,6 +261,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { } public void notifyContentUpdated() { + mPublicLayout.notifyContentUpdated(); mPrivateLayout.notifyContentUpdated(); } + + public boolean isShowingLayoutLayouted() { + NotificationContentView showingLayout = getShowingLayout(); + return showingLayout.getWidth() != 0; + } + + private NotificationContentView getShowingLayout() { + return mShowingPublic ? mPublicLayout : mPrivateLayout; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java index 4233ab8..bfa74fa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java @@ -21,6 +21,7 @@ import android.content.Context; import android.os.Process; import android.provider.Settings; import android.service.notification.NotificationListenerService.Ranking; +import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; @@ -58,17 +59,18 @@ public class InterceptedNotifications { updateSyntheticNotification(); } - public boolean tryIntercept(StatusBarNotification notification, Ranking ranking) { - if (ranking == null) return false; + public boolean tryIntercept(StatusBarNotification notification, RankingMap rankingMap) { + if (rankingMap == null) return false; if (shouldDisplayIntercepted()) return false; if (mReleased.contains(notification.getKey())) return false; - if (!ranking.isInterceptedByDoNotDisturb(notification.getKey())) return false; + Ranking ranking = rankingMap.getRanking(notification.getKey()); + if (!ranking.isInterceptedByDoNotDisturb()) return false; mIntercepted.put(notification.getKey(), notification); updateSyntheticNotification(); return true; } - public void retryIntercepts(Ranking ranking) { + public void retryIntercepts(RankingMap ranking) { if (ranking == null) return; final int N = mIntercepted.size(); @@ -111,7 +113,7 @@ public class InterceptedNotifications { return; } final Notification n = new Notification.Builder(mContext) - .setSmallIcon(R.drawable.ic_qs_zen_on) + .setSmallIcon(R.drawable.ic_notify_zen) .setContentTitle(mContext.getResources().getQuantityString( R.plurals.zen_mode_notification_title, mIntercepted.size(), mIntercepted.size())) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index f9baecb..5cde979 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -106,7 +106,7 @@ public class NotificationContentView extends FrameLayout { private void selectLayout() { if (mActualHeight <= mSmallHeight || mExpandedChild == null) { - if (mContractedChild.getVisibility() != View.VISIBLE) { + if (mContractedChild != null && mContractedChild.getVisibility() != View.VISIBLE) { mContractedChild.setVisibility(View.VISIBLE); } if (mExpandedChild != null && mExpandedChild.getVisibility() != View.INVISIBLE) { @@ -116,7 +116,7 @@ public class NotificationContentView extends FrameLayout { if (mExpandedChild.getVisibility() != View.VISIBLE) { mExpandedChild.setVisibility(View.VISIBLE); } - if (mContractedChild.getVisibility() != View.INVISIBLE) { + if (mContractedChild != null && mContractedChild.getVisibility() != View.INVISIBLE) { mContractedChild.setVisibility(View.INVISIBLE); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index d829ac0..c313c58 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar; import android.app.Notification; import android.service.notification.NotificationListenerService.Ranking; +import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; import android.view.View; @@ -40,6 +41,9 @@ public class NotificationData { public View expandedPublic; // for insecure lockscreens public View expandedBig; private boolean interruption; + public boolean autoRedacted; // whether the redacted notification was generated by us + public boolean legacy; // whether the notification has a legacy, dark background + public Entry() {} public Entry(StatusBarNotification n, StatusBarIconView ic) { this.key = n.getKey(); @@ -67,12 +71,16 @@ public class NotificationData { } private final ArrayList<Entry> mEntries = new ArrayList<Entry>(); - private Ranking mRanking; + private RankingMap mRanking; private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() { @Override public int compare(Entry a, Entry b) { if (mRanking != null) { - return mRanking.getRank(a.key) - mRanking.getRank(b.key); + Ranking aRanking = mRanking.getRanking(a.key); + Ranking bRanking = mRanking.getRanking(b.key); + int aRank = aRanking != null ? aRanking.getRank() : -1; + int bRank = bRanking != null ? bRanking.getRank() : -1; + return aRank - bRank; } final StatusBarNotification na = a.notification; @@ -105,12 +113,12 @@ public class NotificationData { return null; } - public void add(Entry entry, Ranking ranking) { + public void add(Entry entry, RankingMap ranking) { mEntries.add(entry); updateRankingAndSort(ranking); } - public Entry remove(String key, Ranking ranking) { + public Entry remove(String key, RankingMap ranking) { Entry e = findByKey(key); if (e == null) { return null; @@ -120,7 +128,7 @@ public class NotificationData { return e; } - public void updateRanking(Ranking ranking) { + public void updateRanking(RankingMap ranking) { updateRankingAndSort(ranking); } @@ -134,12 +142,13 @@ public class NotificationData { } } } else { - return mRanking.isAmbient(key); + Ranking ranking = mRanking.getRanking(key); + return ranking != null && ranking.isAmbient(); } return false; } - private void updateRankingAndSort(Ranking ranking) { + private void updateRankingAndSort(RankingMap ranking) { if (ranking != null) { mRanking = ranking; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java index 6819d9b..ce5ab5a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java @@ -65,7 +65,7 @@ public class NotificationOverflowIconsView extends IconMerger { } private void applyColor(Notification notification, StatusBarIconView view) { - if (notification.color != Notification.COLOR_DEFAULT) { + if (notification.color == Notification.COLOR_DEFAULT) { if (mNotificationColorUtil.isGrayscale(view.getDrawable())) { view.setColorFilter(mTintColor, PorterDuff.Mode.MULTIPLY); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java deleted file mode 100644 index 1503072..0000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2014 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; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Outline; -import android.graphics.Paint; -import android.util.AttributeSet; -import android.view.View; - -/** - * An single dot of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout} - */ -public class SpeedBumpDotView extends View { - - private final Paint mPaint = new Paint(); - - public SpeedBumpDotView(Context context, AttributeSet attrs) { - super(context, attrs); - mPaint.setAntiAlias(true); - } - - @Override - protected void onDraw(Canvas canvas) { - float radius = getWidth() / 2.0f; - canvas.drawCircle(radius, radius, radius, mPaint); - } - - @Override - public boolean hasOverlappingRendering() { - return false; - } - - public void setColor(int color) { - mPaint.setColor(color); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java deleted file mode 100644 index cac6327..0000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2014 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; - -import android.content.Context; -import android.view.View; -import com.android.systemui.R; - -/** - * The Algorithm of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout} which can be - * queried for {@link * com.android.systemui.statusbar.SpeedBumpDotsState} - */ -public class SpeedBumpDotsAlgorithm { - - private final float mDotRadius; - - public SpeedBumpDotsAlgorithm(Context context) { - mDotRadius = context.getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height) - / 2.0f; - } - - public void getState(SpeedBumpDotsState resultState) { - - // First reset the current state and ensure that every View has a ViewState - resultState.resetViewStates(); - - SpeedBumpDotsLayout hostView = resultState.getHostView(); - boolean currentlyVisible = hostView.isCurrentlyVisible(); - resultState.setActiveState(currentlyVisible - ? SpeedBumpDotsState.SHOWN - : SpeedBumpDotsState.HIDDEN); - int hostWidth = hostView.getWidth(); - float layoutWidth = hostWidth - 2 * mDotRadius; - int childCount = hostView.getChildCount(); - float paddingBetween = layoutWidth / (childCount - 1); - float centerY = hostView.getHeight() / 2.0f; - for (int i = 0; i < childCount; i++) { - View child = hostView.getChildAt(i); - SpeedBumpDotsState.ViewState viewState = resultState.getViewStateForView(child); - if (currentlyVisible) { - float xTranslation = i * paddingBetween; - viewState.xTranslation = xTranslation; - viewState.yTranslation = calculateYTranslation(hostView, centerY, xTranslation, - layoutWidth); - } else { - viewState.xTranslation = layoutWidth / 2; - viewState.yTranslation = centerY - mDotRadius; - } - viewState.alpha = currentlyVisible ? 1.0f : 0.0f; - viewState.scale = currentlyVisible ? 1.0f : 0.5f; - } - } - - private float calculateYTranslation(SpeedBumpDotsLayout hostView, float centerY, - float xTranslation, float layoutWidth) { - float t = hostView.getAnimationProgress(); - if (t == 0.0f || t == 1.0f) { - return centerY - mDotRadius; - } - float damping = (0.5f -Math.abs(0.5f - t)) * 1.3f; - float partialOffset = xTranslation / layoutWidth; - float indentFactor = (float) (Math.sin((t + partialOffset * 1.5f) * - Math.PI) * damping); - return (1.0f - indentFactor) * centerY - mDotRadius; - } - -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java deleted file mode 100644 index ddf5215..0000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2014 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; - -import android.animation.TimeAnimator; -import android.animation.ValueAnimator; -import android.content.Context; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.AccelerateDecelerateInterpolator; -import com.android.systemui.R; - -/** - * A layout with a certain number of dots which are integrated in the - * {@link com.android.systemui.statusbar.SpeedBumpView} - */ -public class SpeedBumpDotsLayout extends ViewGroup { - - private static final float DOT_CLICK_ANIMATION_LENGTH = 300; - private final int mDotSize; - private final SpeedBumpDotsAlgorithm mAlgorithm = new SpeedBumpDotsAlgorithm(getContext()); - private final SpeedBumpDotsState mCurrentState = new SpeedBumpDotsState(this); - private boolean mIsCurrentlyVisible = true; - private final ValueAnimator mClickAnimator; - private float mAnimationProgress; - private ValueAnimator.AnimatorUpdateListener mClickUpdateListener - = new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - mAnimationProgress = animation.getAnimatedFraction(); - updateChildren(); - } - }; - - public SpeedBumpDotsLayout(Context context, AttributeSet attrs) { - super(context, attrs); - mDotSize = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height); - createDots(context, attrs); - mClickAnimator = TimeAnimator.ofFloat(0, DOT_CLICK_ANIMATION_LENGTH); - mClickAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); - mClickAnimator.addUpdateListener(mClickUpdateListener); - } - - private void createDots(Context context, AttributeSet attrs) { - SpeedBumpDotView blueDot = new SpeedBumpDotView(context, attrs); - blueDot.setColor(getResources().getColor(R.color.speed_bump_dot_blue)); - addView(blueDot); - - SpeedBumpDotView redDot = new SpeedBumpDotView(context, attrs); - redDot.setColor(getResources().getColor(R.color.speed_bump_dot_red)); - addView(redDot); - - SpeedBumpDotView yellowDot = new SpeedBumpDotView(context, attrs); - yellowDot.setColor(getResources().getColor(R.color.speed_bump_dot_yellow)); - addView(yellowDot); - - SpeedBumpDotView greenDot = new SpeedBumpDotView(context, attrs); - greenDot.setColor(getResources().getColor(R.color.speed_bump_dot_green)); - addView(greenDot); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - int childWidthSpec = MeasureSpec.makeMeasureSpec(mDotSize, - MeasureSpec.getMode(widthMeasureSpec)); - int childHeightSpec = MeasureSpec.makeMeasureSpec(mDotSize, - MeasureSpec.getMode(heightMeasureSpec)); - measureChildren(childWidthSpec, childHeightSpec); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - View child = getChildAt(i); - child.layout(0, 0, mDotSize, mDotSize); - } - if (changed) { - updateChildren(); - } - } - - private void updateChildren() { - mAlgorithm.getState(mCurrentState); - mCurrentState.apply(); - } - - public void performVisibilityAnimation(boolean visible) { - if (mClickAnimator.isRunning()) { - mClickAnimator.cancel(); - } - mIsCurrentlyVisible = visible; - mAlgorithm.getState(mCurrentState); - mCurrentState.animateToState(); - } - - public void setInvisible() { - mIsCurrentlyVisible = false; - mAlgorithm.getState(mCurrentState); - mCurrentState.apply(); - } - - public boolean isCurrentlyVisible() { - return mIsCurrentlyVisible; - } - - public void performDotClickAnimation() { - if (mClickAnimator.isRunning()) { - // don't perform an animation if it's running already - return; - } - mClickAnimator.start(); - } - - - public float getAnimationProgress() { - return mAnimationProgress; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java deleted file mode 100644 index 4febab1..0000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2014 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; - -import android.view.View; -import android.view.ViewPropertyAnimator; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; - -import java.util.HashMap; -import java.util.Map; - -/** - * A state of a {@link com.android.systemui.statusbar.SpeedBumpDotsLayout} - */ -public class SpeedBumpDotsState { - - public static final int HIDDEN = 1; - public static final int SHOWN = 2; - private static final int VISIBILITY_ANIMATION_DELAY_PER_ELEMENT = 80; - - private final SpeedBumpDotsLayout mHostView; - private final HashMap<View, ViewState> mStateMap = new HashMap<View, ViewState>(); - private final Interpolator mFastOutSlowInInterpolator; - private int mActiveState = 0; - - public SpeedBumpDotsState(SpeedBumpDotsLayout hostLayout) { - mHostView = hostLayout; - mFastOutSlowInInterpolator = AnimationUtils - .loadInterpolator(hostLayout.getContext(), - android.R.interpolator.fast_out_slow_in); - } - - public SpeedBumpDotsLayout getHostView() { - return mHostView; - } - - public void resetViewStates() { - int numChildren = mHostView.getChildCount(); - for (int i = 0; i < numChildren; i++) { - View child = mHostView.getChildAt(i); - ViewState viewState = mStateMap.get(child); - if (viewState == null) { - viewState = new ViewState(); - mStateMap.put(child, viewState); - } - } - } - - public ViewState getViewStateForView(View requestedView) { - return mStateMap.get(requestedView); - } - - public void apply() { - int childCount = mHostView.getChildCount(); - for (int i = 0; i < childCount; i++) { - View child = mHostView.getChildAt(i); - ViewState viewState = mStateMap.get(child); - - child.setTranslationX(viewState.xTranslation); - child.setTranslationY(viewState.yTranslation); - child.setScaleX(viewState.scale); - child.setScaleY(viewState.scale); - child.setAlpha(viewState.alpha); - } - } - - public void animateToState() { - int childCount = mHostView.getChildCount(); - int middleIndex = (childCount - 1) / 2; - long delayPerElement = VISIBILITY_ANIMATION_DELAY_PER_ELEMENT; - boolean isAppearing = getActiveState() == SHOWN; - boolean isDisappearing = getActiveState() == HIDDEN; - for (int i = 0; i < childCount; i++) { - int delayIndex; - if (i <= middleIndex) { - delayIndex = i * 2; - } else { - int distToMiddle = i - middleIndex; - delayIndex = (childCount - 1) - (distToMiddle - 1) * 2; - } - long startDelay = 0; - if (isAppearing || isDisappearing) { - if (isDisappearing) { - delayIndex = childCount - 1 - delayIndex; - } - startDelay = delayIndex * delayPerElement; - } - View child = mHostView.getChildAt(i); - ViewState viewState = mStateMap.get(child); - child.animate().setInterpolator(mFastOutSlowInInterpolator) - .setStartDelay(startDelay) - .alpha(viewState.alpha) - .translationX(viewState.xTranslation) - .translationY(viewState.yTranslation) - .scaleX(viewState.scale).scaleY(viewState.scale); - } - } - - public int getActiveState() { - return mActiveState; - } - - public void setActiveState(int mActiveState) { - this.mActiveState = mActiveState; - } - - public static class ViewState { - float xTranslation; - float yTranslation; - float alpha; - float scale; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java index 689d0e9..f80f0fd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java @@ -16,71 +16,26 @@ package com.android.systemui.statusbar; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; import android.content.Context; -import android.graphics.Outline; import android.util.AttributeSet; -import android.view.View; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; -import android.widget.TextView; import com.android.systemui.R; /** * The view representing the separation between important and less important notifications */ -public class SpeedBumpView extends ExpandableView implements View.OnClickListener { +public class SpeedBumpView extends ExpandableView { - private final int mCollapsedHeight; - private final int mDotsHeight; - private final int mTextPaddingInset; - private SpeedBumpDotsLayout mDots; - private AlphaOptimizedView mLineLeft; - private AlphaOptimizedView mLineRight; - private boolean mIsExpanded; - private boolean mDividerVisible = true; - private ValueAnimator mCurrentAnimator; + private final int mSpeedBumpHeight; + private AlphaOptimizedView mLine; + private boolean mIsVisible = true; private final Interpolator mFastOutSlowInInterpolator; - private float mCenterX; - private TextView mExplanationText; - private boolean mExplanationTextVisible = false; - private AnimatorListenerAdapter mHideExplanationListener = new AnimatorListenerAdapter() { - private boolean mCancelled; - - @Override - public void onAnimationEnd(Animator animation) { - if (!mCancelled) { - mExplanationText.setVisibility(View.INVISIBLE); - } - } - - @Override - public void onAnimationCancel(Animator animation) { - mCancelled = true; - } - - @Override - public void onAnimationStart(Animator animation) { - mCancelled = false; - } - }; - private Animator.AnimatorListener mAnimationFinishedListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mCurrentAnimator = null; - } - }; public SpeedBumpView(Context context, AttributeSet attrs) { super(context, attrs); - mCollapsedHeight = getResources() - .getDimensionPixelSize(R.dimen.speed_bump_height_collapsed); - mTextPaddingInset = getResources().getDimensionPixelSize( - R.dimen.speed_bump_text_padding_inset); - mDotsHeight = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height); - setOnClickListener(this); + mSpeedBumpHeight = getResources() + .getDimensionPixelSize(R.dimen.speed_bump_height); mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(), android.R.interpolator.fast_out_slow_in); } @@ -88,111 +43,41 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene @Override protected void onFinishInflate() { super.onFinishInflate(); - mDots = (SpeedBumpDotsLayout) findViewById(R.id.speed_bump_dots_layout); - mLineLeft = (AlphaOptimizedView) findViewById(R.id.speedbump_line_left); - mLineRight = (AlphaOptimizedView) findViewById(R.id.speedbump_line_right); - mExplanationText = (TextView) findViewById(R.id.speed_bump_text); - resetExplanationText(); - + mLine = (AlphaOptimizedView) findViewById(R.id.speedbump_line); } @Override protected int getInitialHeight() { - return mCollapsedHeight; + return mSpeedBumpHeight; } @Override public int getIntrinsicHeight() { - if (mCurrentAnimator != null) { - // expand animation is running - return getActualHeight(); - } - return mIsExpanded ? getHeight() : mCollapsedHeight; + return mSpeedBumpHeight; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - Outline outline = new Outline(); - mCenterX = getWidth() / 2; - float centerY = getHeight() / 2; - // TODO: hide outline better - // Temporary workaround to hide outline on a transparent view - int outlineLeft = (int) (mCenterX - getResources().getDisplayMetrics().densityDpi * 8); - int outlineTop = (int) (centerY - mDotsHeight / 2); - outline.setOval(outlineLeft, outlineTop, outlineLeft + mDotsHeight, - outlineTop + mDotsHeight); - setOutline(outline); - mLineLeft.setPivotX(mLineLeft.getWidth()); - mLineLeft.setPivotY(mLineLeft.getHeight() / 2); - mLineRight.setPivotX(0); - mLineRight.setPivotY(mLineRight.getHeight() / 2); + mLine.setPivotX(mLine.getWidth() / 2); + mLine.setPivotY(mLine.getHeight() / 2); + setOutline(null); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { measureChildren(widthMeasureSpec, heightMeasureSpec); - int height = mCollapsedHeight + mExplanationText.getMeasuredHeight() - mTextPaddingInset; + int height = mSpeedBumpHeight; setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height); } @Override - public void onClick(View v) { - if (mCurrentAnimator != null) { - return; - } - int startValue = mIsExpanded ? getMaxHeight() : mCollapsedHeight; - int endValue = mIsExpanded ? mCollapsedHeight : getMaxHeight(); - mCurrentAnimator = ValueAnimator.ofInt(startValue, endValue); - mCurrentAnimator.setInterpolator(mFastOutSlowInInterpolator); - mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - setActualHeight((int) animation.getAnimatedValue()); - } - }); - mCurrentAnimator.addListener(mAnimationFinishedListener); - mCurrentAnimator.start(); - mIsExpanded = !mIsExpanded; - mDots.performDotClickAnimation(); - animateExplanationTextInternal(mIsExpanded); - } - - private void animateExplanationTextInternal(boolean visible) { - if (mExplanationTextVisible != visible) { - float translationY = 0.0f; - float scale = 0.5f; - float alpha = 0.0f; - boolean needsHideListener = true; - if (visible) { - mExplanationText.setVisibility(VISIBLE); - translationY = mDots.getBottom() - mTextPaddingInset; - scale = 1.0f; - alpha = 1.0f; - needsHideListener = false; - } - mExplanationText.animate().setInterpolator(mFastOutSlowInInterpolator) - .alpha(alpha) - .scaleX(scale) - .scaleY(scale) - .translationY(translationY) - .setListener(needsHideListener ? mHideExplanationListener : null); - mExplanationTextVisible = visible; - } - } - - @Override public boolean isTransparent() { return true; } public void performVisibilityAnimation(boolean nowVisible) { animateDivider(nowVisible, null /* onFinishedRunnable */); - - // Animate explanation Text - if (mIsExpanded) { - animateExplanationTextInternal(nowVisible); - } } /** @@ -203,28 +88,16 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene * finished. */ public void animateDivider(boolean nowVisible, Runnable onFinishedRunnable) { - if (nowVisible != mDividerVisible) { + if (nowVisible != mIsVisible) { // Animate dividers float endValue = nowVisible ? 1.0f : 0.0f; - float endTranslationXLeft = nowVisible ? 0.0f : mCenterX - mLineLeft.getRight(); - float endTranslationXRight = nowVisible ? 0.0f : mCenterX - mLineRight.getLeft(); - mLineLeft.animate() + mLine.animate() .alpha(endValue) .scaleX(endValue) .scaleY(endValue) - .translationX(endTranslationXLeft) .setInterpolator(mFastOutSlowInInterpolator) .withEndAction(onFinishedRunnable); - mLineRight.animate() - .alpha(endValue) - .scaleX(endValue) - .scaleY(endValue) - .translationX(endTranslationXRight) - .setInterpolator(mFastOutSlowInInterpolator); - - // Animate dots - mDots.performVisibilityAnimation(nowVisible); - mDividerVisible = nowVisible; + mIsVisible = nowVisible; } else { if (onFinishedRunnable != null) { onFinishedRunnable.run(); @@ -233,34 +106,10 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene } public void setInvisible() { - float endTranslationXLeft = mCenterX - mLineLeft.getRight(); - float endTranslationXRight = mCenterX - mLineRight.getLeft(); - mLineLeft.setAlpha(0.0f); - mLineLeft.setScaleX(0.0f); - mLineLeft.setScaleY(0.0f); - mLineLeft.setTranslationX(endTranslationXLeft); - mLineRight.setAlpha(0.0f); - mLineRight.setScaleX(0.0f); - mLineRight.setScaleY(0.0f); - mLineRight.setTranslationX(endTranslationXRight); - mDots.setInvisible(); - resetExplanationText(); - - mDividerVisible = false; - } - - public void collapse() { - if (mIsExpanded) { - setActualHeight(mCollapsedHeight); - mIsExpanded = false; - } - resetExplanationText(); - } - - public void animateExplanationText(boolean nowVisible) { - if (mIsExpanded) { - animateExplanationTextInternal(nowVisible); - } + mLine.setAlpha(0.0f); + mLine.setScaleX(0.0f); + mLine.setScaleY(0.0f); + mIsVisible = false; } @Override @@ -272,17 +121,4 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene public void performAddAnimation(long delay) { performVisibilityAnimation(true); } - - private void resetExplanationText() { - mExplanationText.setTranslationY(0); - mExplanationText.setVisibility(INVISIBLE); - mExplanationText.setAlpha(0.0f); - mExplanationText.setScaleX(0.5f); - mExplanationText.setScaleY(0.5f); - mExplanationTextVisible = false; - } - - public boolean isExpanded() { - return mIsExpanded; - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java index 086a266..e312d58 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java @@ -423,6 +423,7 @@ public class KeyguardPageSwipeHelper { return; } if (!animate) { + view.animate().cancel(); view.setAlpha(alpha); view.setScaleX(scale); view.setScaleY(scale); @@ -465,6 +466,13 @@ public class KeyguardPageSwipeHelper { } public void reset() { + if (mSwipeAnimator != null) { + mSwipeAnimator.cancel(); + } + ArrayList<View> targetViews = mCallback.getTranslationViews(); + for (View view : targetViews) { + view.animate().cancel(); + } setTranslation(0.0f, true); mSwipingInProgress = false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index 772d0e7..1f3098d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -27,6 +27,7 @@ import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.ViewConfiguration; +import android.view.ViewTreeObserver; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.FrameLayout; @@ -67,6 +68,11 @@ public abstract class PanelView extends FrameLayout { private VelocityTrackerInterface mVelocityTracker; private FlingAnimationUtils mFlingAnimationUtils; + /** + * Whether an instant expand request is currently pending and we are just waiting for layout. + */ + private boolean mInstantExpanding; + PanelBar mBar; protected int mMaxPanelHeight = -1; @@ -128,6 +134,9 @@ public abstract class PanelView extends FrameLayout { @Override public boolean onTouchEvent(MotionEvent event) { + if (mInstantExpanding) { + return false; + } /* * We capture touch events here and update the expand height here in case according to @@ -263,6 +272,9 @@ public abstract class PanelView extends FrameLayout { @Override public boolean onInterceptTouchEvent(MotionEvent event) { + if (mInstantExpanding) { + return false; + } /* * If the user drags anywhere inside the panel we intercept it if he moves his finger @@ -556,6 +568,41 @@ public abstract class PanelView extends FrameLayout { } } + public void instantExpand() { + mInstantExpanding = true; + abortAnimations(); + if (mTracking) { + onTrackingStopped(true /* expands */); // The panel is expanded after this call. + onExpandingFinished(); + } + setVisibility(VISIBLE); + + // Wait for window manager to pickup the change, so we know the maximum height of the panel + // then. + getViewTreeObserver().addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + if (mStatusBar.getStatusBarWindow().getHeight() + != mStatusBar.getStatusBarHeight()) { + getViewTreeObserver().removeOnGlobalLayoutListener(this); + setExpandedFraction(1f); + mInstantExpanding = false; + } + } + }); + + // Make sure a layout really happens. + requestLayout(); + } + + private void abortAnimations() { + cancelPeek(); + if (mHeightAnimator != null) { + mHeightAnimator.cancel(); + } + } + protected void startUnlockHintAnimation() { // We don't need to hint the user if an animation is already running or the user is changing 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 f86572d..4ed1888 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -64,7 +64,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Global; -import android.service.notification.NotificationListenerService.Ranking; +import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.DisplayMetrics; @@ -103,6 +103,7 @@ import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.qs.CircularClipper; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QSTile; +import com.android.systemui.statusbar.ActivatableNotificationView; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DragDownHelper; @@ -277,10 +278,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // the date view DateView mDateView; - // for heads up notifications - private HeadsUpNotificationView mHeadsUpNotificationView; - private int mHeadsUpNotificationDecay; - // on-screen navigation buttons private NavigationBarView mNavigationBarView = null; private int mNavigationBarWindowState = WINDOW_STATE_SHOWING; @@ -366,7 +363,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (!mUseHeadsUp) { Log.d(TAG, "dismissing any existing heads up notification on disable event"); setHeadsUpVisibility(false); - mHeadsUpNotificationView.setNotification(null); + mHeadsUpNotificationView.release(); removeHeadsUpView(); } else { addHeadsUpView(); @@ -818,6 +815,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return mStatusBarView; } + public StatusBarWindowView getStatusBarWindow() { + return mStatusBarWindow; + } + @Override protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) { boolean opaque = false; @@ -1050,7 +1051,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) { + public void addNotificationInternal(StatusBarNotification notification, RankingMap ranking) { if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey()); if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification, ranking)) { // Forward the ranking so we can sort the new notification. @@ -1061,31 +1062,28 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, displayNotification(notification, ranking); } - public void displayNotification(StatusBarNotification notification, - Ranking ranking) { - Entry shadeEntry = createNotificationViews(notification); - if (shadeEntry == null) { - return; - } + public void displayNotification(StatusBarNotification notification, RankingMap ranking) { if (mUseHeadsUp && shouldInterrupt(notification)) { if (DEBUG) Log.d(TAG, "launching notification in heads up mode"); Entry interruptionCandidate = new Entry(notification, null); ViewGroup holder = mHeadsUpNotificationView.getHolder(); if (inflateViewsForHeadsUp(interruptionCandidate, holder)) { mInterruptingNotificationTime = System.currentTimeMillis(); - mInterruptingNotificationEntry = interruptionCandidate; - shadeEntry.setInterruption(); // 1. Populate mHeadsUpNotificationView - mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry); + mHeadsUpNotificationView.showNotification(interruptionCandidate); - // 2. Animate mHeadsUpNotificationView in - mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP); - - // 3. Set alarm to age the notification off - resetHeadsUpDecayTimer(); + // do not show the notification in the shade, yet. + return; } - } else if (notification.getNotification().fullScreenIntent != null) { + } + + Entry shadeEntry = createNotificationViews(notification); + if (shadeEntry == null) { + return; + } + + if (notification.getNotification().fullScreenIntent != null) { // Stop screensaver if the notification has a full-screen intent. // (like an incoming phone call) awakenDreams(); @@ -1100,7 +1098,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // usual case: status bar visible & not immersive // show the ticker if there isn't already a heads up - if (mInterruptingNotificationEntry == null) { + if (mHeadsUpNotificationView.getEntry() == null) { tick(notification, true); } } @@ -1110,31 +1108,64 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, updateExpandedViewPos(EXPANDED_LEAVE_ALONE); } + public void displayNotificationFromHeadsUp(StatusBarNotification notification) { + NotificationData.Entry shadeEntry = createNotificationViews(notification); + if (shadeEntry == null) { + return; + } + shadeEntry.setInterruption(); + + addNotificationViews(shadeEntry, null); + // Recalculate the position of the sliding windows and the titles. + setAreThereNotifications(); + updateExpandedViewPos(EXPANDED_LEAVE_ALONE); + } + @Override public void resetHeadsUpDecayTimer() { - mHandler.removeMessages(MSG_HIDE_HEADS_UP); + mHandler.removeMessages(MSG_DECAY_HEADS_UP); if (mUseHeadsUp && mHeadsUpNotificationDecay > 0 && mHeadsUpNotificationView.isClearable()) { - mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay); + mHandler.sendEmptyMessageDelayed(MSG_DECAY_HEADS_UP, mHeadsUpNotificationDecay); } } @Override - public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) { + public void scheduleHeadsUpOpen() { + mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP); + } + + @Override + public void scheduleHeadsUpClose() { + mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); + } + + @Override + public void scheduleHeadsUpEscalation() { + mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP); + } + + @Override + public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) { super.updateNotificationInternal(notification, ranking); // if we're here, then the notification is already in the shade mIntercepted.remove(notification.getKey()); } @Override - protected void updateRankingInternal(Ranking ranking) { + protected void updateRankingInternal(RankingMap ranking) { mNotificationData.updateRanking(ranking); mIntercepted.retryIntercepts(ranking); updateNotifications(); } @Override - public void removeNotificationInternal(String key, Ranking ranking) { + public void removeNotificationInternal(String key, RankingMap ranking) { + if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null + && key.equals(mHeadsUpNotificationView.getEntry().notification.getKey())) { + mHeadsUpNotificationView.clear(); + } + StatusBarNotification old = removeNotificationViews(key, ranking); if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old); @@ -1147,11 +1178,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Recalculate the position of the sliding windows and the titles. updateExpandedViewPos(EXPANDED_LEAVE_ALONE); - if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null - && old == mInterruptingNotificationEntry.notification) { - mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); - } - if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 && !mNotificationPanel.isTracking() && mState != StatusBarState.KEYGUARD) { animateCollapsePanels(); @@ -1192,9 +1218,21 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, final int vis = ent.notification.getNotification().visibility; if (vis != Notification.VISIBILITY_SECRET) { // when isLockscreenPublicMode() we show the public form of VISIBILITY_PRIVATE notifications - ent.row.setShowingPublic(isLockscreenPublicMode() + boolean showingPublic = isLockscreenPublicMode() && vis == Notification.VISIBILITY_PRIVATE - && !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId())); + && !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId()); + ent.row.setShowingPublic(showingPublic); + if (ent.autoRedacted && ent.legacy) { + if (showingPublic) { + ent.row.setBackgroundResourceIds( + com.android.internal.R.drawable.notification_material_bg, + com.android.internal.R.drawable.notification_material_bg_dim); + } else { + ent.row.setBackgroundResourceIds( + com.android.internal.R.drawable.notification_bg, + com.android.internal.R.drawable.notification_bg_dim); + } + } toShow.add(ent.row); } } @@ -1562,7 +1600,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, case MSG_SHOW_HEADS_UP: setHeadsUpVisibility(true); break; + case MSG_DECAY_HEADS_UP: + mHeadsUpNotificationView.release(); + setHeadsUpVisibility(false); + break; case MSG_HIDE_HEADS_UP: + mHeadsUpNotificationView.release(); setHeadsUpVisibility(false); break; case MSG_ESCALATE_HEADS_UP: @@ -1575,8 +1618,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, /** if the interrupting notification had a fullscreen intent, fire it now. */ private void escalateHeadsUp() { - if (mInterruptingNotificationEntry != null) { - final StatusBarNotification sbn = mInterruptingNotificationEntry.notification; + if (mHeadsUpNotificationView.getEntry() != null) { + final StatusBarNotification sbn = mHeadsUpNotificationView.getEntry().notification; + mHeadsUpNotificationView.release(); final Notification notification = sbn.getNotification(); if (notification.fullScreenIntent != null) { if (DEBUG) @@ -2231,7 +2275,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, pw.print(" mUseHeadsUp="); pw.println(mUseHeadsUp); pw.print(" interrupting package: "); - pw.println(hunStateToString(mInterruptingNotificationEntry)); + pw.println(hunStateToString(mHeadsUpNotificationView.getEntry())); dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions()); if (mNavigationBarView != null) { pw.print(" mNavigationBarWindowState="); @@ -2505,26 +2549,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (!ENABLE_HEADS_UP) 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; - } } public void onHeadsUpDismissed() { - if (mInterruptingNotificationEntry == null) return; - mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP); - if (mHeadsUpNotificationView.isClearable()) { - try { - mBarService.onNotificationClear( - mInterruptingNotificationEntry.notification.getPackageName(), - mInterruptingNotificationEntry.notification.getTag(), - mInterruptingNotificationEntry.notification.getId(), - mInterruptingNotificationEntry.notification.getUserId()); - } catch (android.os.RemoteException ex) { - // oh well - } - } + mHeadsUpNotificationView.dismiss(); } /** @@ -2893,7 +2921,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mNotificationPanel.setKeyguardShowing(false); mScrimController.setKeyguardShowing(false); } - updateStackScrollerState(); updatePublicMode(); updateNotifications(); @@ -2909,6 +2936,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, ? View.INVISIBLE : View.VISIBLE); mStackScroller.setScrollingEnabled(!onKeyguard); mStackScroller.setExpandingEnabled(!onKeyguard); + ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild(); + mStackScroller.setActivatedChild(null); + if (activatedChild != null) { + activatedChild.makeInactive(false /* animate */); + } } public void userActivity() { @@ -2942,22 +2974,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void instantExpandNotificationsPanel() { - // Make our window larger and the panel visible. + // Make our window larger and the panel expanded. makeExpandedVisible(true); - mNotificationPanel.setVisibility(View.VISIBLE); - - // Wait for window manager to pickup the change, so we know the maximum height of the panel - // then. - mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener( - new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - if (mStatusBarWindow.getHeight() != getStatusBarHeight()) { - mNotificationPanel.getViewTreeObserver().removeOnGlobalLayoutListener(this); - mNotificationPanel.setExpandedFraction(1); - } - } - }); + mNotificationPanel.instantExpand(); } private void instantCollapseNotificationPanel() { @@ -2965,9 +2984,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void onActivated(View view) { + public void onActivated(ActivatableNotificationView view) { userActivity(); mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again); + ActivatableNotificationView previousView = mStackScroller.getActivatedChild(); + if (previousView != null) { + previousView.makeInactive(true /* animate */); + } mStackScroller.setActivatedChild(view); } @@ -2980,7 +3003,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void onActivationReset(View view) { + public void onActivationReset(ActivatableNotificationView view) { if (view == mStackScroller.getActivatedChild()) { mKeyguardIndicationController.hideTransientIndication(); mStackScroller.setActivatedChild(null); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index 1916f13..c8ab027 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -146,6 +146,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL updateBrightnessControllerState(); updateZTranslation(); updateClickTargets(); + updateWidth(); if (mQSPanel != null) { mQSPanel.setExpanded(expanded && !overscrolled); } @@ -181,7 +182,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } private void updateWidth() { - int width = mKeyguardShowing ? mKeyguardWidth : mNormalWidth; + int width = (mKeyguardShowing && !mExpanded) ? mKeyguardWidth : mNormalWidth; ViewGroup.LayoutParams lp = getLayoutParams(); if (width != lp.width) { lp.width = width; @@ -335,6 +336,11 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } }; + @Override + public boolean shouldDelayChildPressedState() { + return true; + } + public void setShowEmergencyCallsOnly(boolean show) { mShowEmergencyCallsOnly = show; if (mExpanded) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java index df01c12..d778ccb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java @@ -33,9 +33,9 @@ import com.android.systemui.ExpandHelper; import com.android.systemui.Gefingerpoken; import com.android.systemui.R; import com.android.systemui.SwipeHelper; -import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.NotificationData; +import com.android.systemui.statusbar.phone.PhoneStatusBar; public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback, ViewTreeObserver.OnComputeInternalInsetsListener { @@ -51,7 +51,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. private SwipeHelper mSwipeHelper; private EdgeSwipeHelper mEdgeSwipeHelper; - private BaseStatusBar mBar; + private PhoneStatusBar mBar; private ExpandHelper mExpandHelper; private long mStartTouchTime; @@ -69,7 +69,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay); } - public void setBar(BaseStatusBar bar) { + public void setBar(PhoneStatusBar bar) { mBar = bar; } @@ -77,7 +77,10 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. return mContentHolder; } - public boolean setNotification(NotificationData.Entry headsUp) { + public boolean showNotification(NotificationData.Entry headsUp) { + // bump any previous heads up back to the shade + release(); + mHeadsUp = headsUp; if (mContentHolder != null) { mContentHolder.removeAllViews(); @@ -97,10 +100,46 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. mSwipeHelper.snapChild(mContentHolder, 1f); mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay; + + // 2. Animate mHeadsUpNotificationView in + mBar.scheduleHeadsUpOpen(); + + // 3. Set alarm to age the notification off + mBar.resetHeadsUpDecayTimer(); } return true; } + /** Discard the Heads Up notification. */ + public void clear() { + mHeadsUp = null; + mBar.scheduleHeadsUpClose(); + } + + /** Respond to dismissal of the Heads Up window. */ + public void dismiss() { + if (mHeadsUp == null) return; + if (mHeadsUp.notification.isClearable()) { + mBar.onNotificationClear(mHeadsUp.notification); + } else { + release(); + } + mHeadsUp = null; + mBar.scheduleHeadsUpClose(); + } + + /** Push any current Heads Up notification down into the shade. */ + public void release() { + if (mHeadsUp != null) { + mBar.displayNotificationFromHeadsUp(mHeadsUp.notification); + } + mHeadsUp = null; + } + + public NotificationData.Entry getEntry() { + return mHeadsUp; + } + public boolean isClearable() { return mHeadsUp == null || mHeadsUp.notification.isClearable(); } @@ -125,7 +164,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. if (mHeadsUp != null) { // whoops, we're on already! - setNotification(mHeadsUp); + showNotification(mHeadsUp); } getViewTreeObserver().addOnComputeInternalInsetsListener(this); @@ -282,6 +321,10 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. mTmpTwoArray[1] + mContentHolder.getHeight()); } + public void escalate() { + mBar.scheduleHeadsUpEscalation(); + } + private class EdgeSwipeHelper implements Gefingerpoken { private static final boolean DEBUG_EDGE_SWIPE = false; private final float mTouchSlop; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index dc8f315..1f68860 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -30,7 +30,7 @@ public interface NetworkController { void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId, String mobileSignalContentDescriptionId, int dataTypeIconId, boolean activityIn, boolean activityOut, - String dataTypeContentDescriptionId, String description); + String dataTypeContentDescriptionId, String description, boolean noSim); void onAirplaneModeChanged(boolean enabled); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index bf908fe..4e54e41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -88,6 +88,7 @@ public class NetworkControllerImpl extends BroadcastReceiver int mQSDataTypeIconId; int mAirplaneIconId; boolean mDataActive; + boolean mNoSim; int mLastSignalLevel; boolean mShowPhoneRSSIForData = false; boolean mShowAtLeastThreeGees = false; @@ -350,18 +351,18 @@ public class NetworkControllerImpl extends BroadcastReceiver if (isEmergencyOnly()) { cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId, mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut, - mContentDescriptionDataType, null); + mContentDescriptionDataType, null, mNoSim); } else { if (mIsWimaxEnabled && mWimaxConnected) { // Wimax is special cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId, mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut, - mContentDescriptionDataType, mNetworkName); + mContentDescriptionDataType, mNetworkName, mNoSim); } else { // Normal mobile data cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId, mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut, - mContentDescriptionDataType, mNetworkName); + mContentDescriptionDataType, mNetworkName, mNoSim); } } cb.onAirplaneModeChanged(mAirplaneMode); @@ -737,6 +738,7 @@ public class NetworkControllerImpl extends BroadcastReceiver // GSM case, we have to check also the sim state if (mSimState == IccCardConstants.State.READY || mSimState == IccCardConstants.State.UNKNOWN) { + mNoSim = false; if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { switch (mDataActivity) { case TelephonyManager.DATA_ACTIVITY_IN: @@ -759,6 +761,7 @@ public class NetworkControllerImpl extends BroadcastReceiver } } else { iconId = R.drawable.stat_sys_no_sim; + mNoSim = true; visible = false; // no SIM? no data } } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java index b21e12c..6d92b05 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.stack; import android.view.View; +import com.android.systemui.statusbar.ActivatableNotificationView; import java.util.ArrayList; @@ -27,7 +28,7 @@ public class AmbientState { private ArrayList<View> mDraggedViews = new ArrayList<View>(); private int mScrollY; private boolean mDimmed; - private View mActivatedChild; + private ActivatableNotificationView mActivatedChild; private float mOverScrollTopAmount; private float mOverScrollBottomAmount; private int mSpeedBumpIndex = -1; @@ -64,7 +65,7 @@ public class AmbientState { * In dimmed mode, a child can be activated, which happens on the first tap of the double-tap * interaction. This child is then scaled normally and its background is fully opaque. */ - public void setActivatedChild(View activatedChild) { + public void setActivatedChild(ActivatableNotificationView activatedChild) { mActivatedChild = activatedChild; } @@ -72,7 +73,7 @@ public class AmbientState { return mDimmed; } - public View getActivatedChild() { + public ActivatableNotificationView getActivatedChild() { return mActivatedChild; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 20caed8..94472a3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -33,6 +33,7 @@ import android.widget.OverScroller; import com.android.systemui.ExpandHelper; import com.android.systemui.R; import com.android.systemui.SwipeHelper; +import com.android.systemui.statusbar.ActivatableNotificationView; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.SpeedBumpView; @@ -1722,7 +1723,6 @@ public class NotificationStackScrollLayout extends ViewGroup mStackScrollAlgorithm.setIsExpanded(isExpanded); if (!isExpanded) { mOwnScrollY = 0; - mSpeedBumpView.collapse(); } } @@ -1760,7 +1760,7 @@ public class NotificationStackScrollLayout extends ViewGroup /** * See {@link AmbientState#setActivatedChild}. */ - public void setActivatedChild(View activatedChild) { + public void setActivatedChild(ActivatableNotificationView activatedChild) { mAmbientState.setActivatedChild(activatedChild); if (mAnimationsEnabled) { mActivateNeedsAnimation = true; @@ -1769,7 +1769,7 @@ public class NotificationStackScrollLayout extends ViewGroup requestChildrenUpdate(); } - public View getActivatedChild() { + public ActivatableNotificationView getActivatedChild() { return mAmbientState.getActivatedChild(); } @@ -1791,7 +1791,6 @@ public class NotificationStackScrollLayout extends ViewGroup int newVisibility = visible ? VISIBLE : GONE; mSpeedBumpView.setVisibility(newVisibility); if (visible) { - mSpeedBumpView.collapse(); // Make invisible to ensure that the appear animation is played. mSpeedBumpView.setInvisible(); if (!mIsExpansionChanging) { @@ -1835,6 +1834,11 @@ public class NotificationStackScrollLayout extends ViewGroup return super.dispatchTouchEvent(ev); } + @Override + public boolean shouldDelayChildPressedState() { + return true; + } + /** * A listener that is notified when some child locations might have changed. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index b41f87b..d6ff4fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -662,7 +662,7 @@ public class StackScrollAlgorithm { } else { // We are expanding the shade, expand it to its full height. - if (mFirstChildWhileExpanding.getWidth() == 0) { + if (!isMaxSizeInitialized(mFirstChildWhileExpanding)) { // This child was not layouted yet, wait for a layout pass mFirstChildWhileExpanding @@ -689,6 +689,14 @@ public class StackScrollAlgorithm { } } + private boolean isMaxSizeInitialized(ExpandableView child) { + if (child instanceof ExpandableNotificationRow) { + ExpandableNotificationRow row = (ExpandableNotificationRow) child; + return row.isShowingLayoutLayouted(); + } + return child == null || child.getWidth() != 0; + } + private View findFirstVisibleChild(ViewGroup container) { int childCount = container.getChildCount(); for (int i = 0; i < childCount; i++) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java index 94cb16d..1ad4acc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java @@ -160,9 +160,8 @@ public class StackScrollState { } if(child instanceof SpeedBumpView) { - float speedBumpEnd = newYTranslation + newHeight; - performSpeedBumpAnimation(i, (SpeedBumpView) child, speedBumpEnd, - newYTranslation); + float lineEnd = newYTranslation + newHeight / 2; + performSpeedBumpAnimation(i, (SpeedBumpView) child, lineEnd); } } } @@ -183,20 +182,12 @@ public class StackScrollState { child.setClipBounds(mClipRect); } - private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd, - float speedBumpStart) { + private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd) { View nextChild = getNextChildNotGone(i); if (nextChild != null) { ViewState nextState = getViewStateForView(nextChild); - boolean startIsAboveNext = nextState.yTranslation > speedBumpStart; + boolean startIsAboveNext = nextState.yTranslation > speedBumpEnd; speedBump.animateDivider(startIsAboveNext, null /* onFinishedRunnable */); - - // handle expanded case - if (speedBump.isExpanded()) { - boolean endIsAboveNext = nextState.yTranslation > speedBumpEnd; - speedBump.animateExplanationText(endIsAboveNext); - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java index faea8de..9260aac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -17,14 +17,14 @@ package com.android.systemui.statusbar.tv; import android.os.IBinder; -import android.service.notification.NotificationListenerService; -import android.service.notification.NotificationListenerService.Ranking; +import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; import com.android.internal.statusbar.StatusBarIcon; +import com.android.systemui.statusbar.ActivatableNotificationView; import com.android.systemui.statusbar.BaseStatusBar; /* @@ -51,11 +51,11 @@ public class TvStatusBar extends BaseStatusBar { } @Override - public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) { + public void addNotificationInternal(StatusBarNotification notification, RankingMap ranking) { } @Override - protected void updateRankingInternal(Ranking ranking) { + protected void updateRankingInternal(RankingMap ranking) { } @Override @@ -63,7 +63,7 @@ public class TvStatusBar extends BaseStatusBar { } @Override - public void removeNotificationInternal(String key, Ranking ranking) { + public void removeNotificationInternal(String key, RankingMap ranking) { } @Override @@ -147,6 +147,18 @@ public class TvStatusBar extends BaseStatusBar { } @Override + public void scheduleHeadsUpOpen() { + } + + @Override + public void scheduleHeadsUpEscalation() { + } + + @Override + public void scheduleHeadsUpClose() { + } + + @Override protected int getMaxKeyguardNotifications() { return 0; } @@ -164,10 +176,10 @@ public class TvStatusBar extends BaseStatusBar { } @Override - public void onActivated(View view) { + public void onActivated(ActivatableNotificationView view) { } @Override - public void onActivationReset(View view) { + public void onActivationReset(ActivatableNotificationView view) { } } |
