Merge changes I089fa8ff,I8db745c1,I6fa83189 into qt-r1-dev
* changes: Showing heads up for music when bypassing Not rendering background when bypassing Made sure the lock icon is invisible while hunned
This commit is contained in:
@@ -8275,6 +8275,16 @@ public final class Settings {
|
||||
private static final Validator FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR =
|
||||
BOOLEAN_VALIDATOR;
|
||||
|
||||
/**
|
||||
* Whether or not media is shown automatically when bypassing as a heads up.
|
||||
* @hide
|
||||
*/
|
||||
public static final String SHOW_MEDIA_WHEN_BYPASSING =
|
||||
"show_media_when_bypassing";
|
||||
|
||||
private static final Validator SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR =
|
||||
BOOLEAN_VALIDATOR;
|
||||
|
||||
/**
|
||||
* Whether or not face unlock requires attention. This is a cached value, the source of
|
||||
* truth is obtained through the HAL.
|
||||
@@ -8979,6 +8989,7 @@ public final class Settings {
|
||||
NFC_PAYMENT_DEFAULT_COMPONENT,
|
||||
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
|
||||
FACE_UNLOCK_KEYGUARD_ENABLED,
|
||||
SHOW_MEDIA_WHEN_BYPASSING,
|
||||
FACE_UNLOCK_DISMISSES_KEYGUARD,
|
||||
FACE_UNLOCK_APP_ENABLED,
|
||||
FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
|
||||
@@ -9155,6 +9166,7 @@ public final class Settings {
|
||||
VALIDATORS.put(FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR);
|
||||
VALIDATORS.put(FACE_UNLOCK_DISMISSES_KEYGUARD,
|
||||
FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR);
|
||||
VALIDATORS.put(SHOW_MEDIA_WHEN_BYPASSING, SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR);
|
||||
VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR);
|
||||
VALIDATORS.put(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
|
||||
FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR);
|
||||
|
||||
@@ -138,6 +138,9 @@
|
||||
<!-- The number of milliseconds before the heads up notification auto-dismisses. -->
|
||||
<integer name="heads_up_notification_decay">5000</integer>
|
||||
|
||||
<!-- The number of milliseconds before the heads up notification sent automatically by the system auto-dismisses. -->
|
||||
<integer name="auto_heads_up_notification_decay">3000</integer>
|
||||
|
||||
<!-- The number of milliseconds after a heads up notification is pushed back
|
||||
before the app can interrupt again. -->
|
||||
<integer name="heads_up_default_snooze_length_ms">60000</integer>
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.NotificationMediaManager;
|
||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.statusbar.policy.NextAlarmController;
|
||||
import com.android.systemui.statusbar.policy.NextAlarmControllerImpl;
|
||||
@@ -103,8 +104,8 @@ public class KeyguardSliceProvider extends SliceProvider implements
|
||||
private final Date mCurrentTime = new Date();
|
||||
private final Handler mHandler;
|
||||
private final AlarmManager.OnAlarmListener mUpdateNextAlarm = this::updateNextAlarm;
|
||||
private final HashSet<Integer> mMediaInvisibleStates;
|
||||
private final Object mMediaToken = new Object();
|
||||
private DozeParameters mDozeParameters;
|
||||
@VisibleForTesting
|
||||
protected SettableWakeLock mMediaWakeLock;
|
||||
@VisibleForTesting
|
||||
@@ -184,11 +185,6 @@ public class KeyguardSliceProvider extends SliceProvider implements
|
||||
mAlarmUri = Uri.parse(KEYGUARD_NEXT_ALARM_URI);
|
||||
mDndUri = Uri.parse(KEYGUARD_DND_URI);
|
||||
mMediaUri = Uri.parse(KEYGUARD_MEDIA_URI);
|
||||
|
||||
mMediaInvisibleStates = new HashSet<>();
|
||||
mMediaInvisibleStates.add(PlaybackState.STATE_NONE);
|
||||
mMediaInvisibleStates.add(PlaybackState.STATE_STOPPED);
|
||||
mMediaInvisibleStates.add(PlaybackState.STATE_PAUSED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,12 +197,14 @@ public class KeyguardSliceProvider extends SliceProvider implements
|
||||
public void initDependencies(
|
||||
NotificationMediaManager mediaManager,
|
||||
StatusBarStateController statusBarStateController,
|
||||
KeyguardBypassController keyguardBypassController) {
|
||||
KeyguardBypassController keyguardBypassController,
|
||||
DozeParameters dozeParameters) {
|
||||
mMediaManager = mediaManager;
|
||||
mMediaManager.addCallback(this);
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mStatusBarStateController.addCallback(this);
|
||||
mKeyguardBypassController = keyguardBypassController;
|
||||
mDozeParameters = dozeParameters;
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@@ -231,9 +229,9 @@ public class KeyguardSliceProvider extends SliceProvider implements
|
||||
}
|
||||
|
||||
protected boolean needsMediaLocked() {
|
||||
boolean isBypass = mKeyguardBypassController != null
|
||||
&& mKeyguardBypassController.getBypassEnabled();
|
||||
return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && (mDozing || isBypass);
|
||||
boolean keepWhenAwake = mKeyguardBypassController != null
|
||||
&& mKeyguardBypassController.getBypassEnabled() && mDozeParameters.getAlwaysOn();
|
||||
return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && (mDozing || keepWhenAwake);
|
||||
}
|
||||
|
||||
protected void addMediaLocked(ListBuilder listBuilder) {
|
||||
@@ -458,7 +456,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
|
||||
@Override
|
||||
public void onMetadataOrStateChanged(MediaMetadata metadata, @PlaybackState.State int state) {
|
||||
synchronized (this) {
|
||||
boolean nextVisible = !mMediaInvisibleStates.contains(state);
|
||||
boolean nextVisible = NotificationMediaManager.isPlayingState(state);
|
||||
mHandler.removeCallbacksAndMessages(mMediaToken);
|
||||
if (mMediaIsVisible && !nextVisible) {
|
||||
// We need to delay this event for a few millis when stopping to avoid jank in the
|
||||
@@ -477,7 +475,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
|
||||
}
|
||||
|
||||
private void updateMediaStateLocked(MediaMetadata metadata, @PlaybackState.State int state) {
|
||||
boolean nextVisible = !mMediaInvisibleStates.contains(state);
|
||||
boolean nextVisible = NotificationMediaManager.isPlayingState(state);
|
||||
CharSequence title = null;
|
||||
if (metadata != null) {
|
||||
title = metadata.getText(MediaMetadata.METADATA_KEY_TITLE);
|
||||
|
||||
@@ -69,6 +69,7 @@ import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -91,6 +92,14 @@ public class NotificationMediaManager implements Dumpable {
|
||||
private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
|
||||
private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
|
||||
private final KeyguardBypassController mKeyguardBypassController;
|
||||
private static final HashSet<Integer> PAUSED_MEDIA_STATES = new HashSet<>();
|
||||
static {
|
||||
PAUSED_MEDIA_STATES.add(PlaybackState.STATE_NONE);
|
||||
PAUSED_MEDIA_STATES.add(PlaybackState.STATE_STOPPED);
|
||||
PAUSED_MEDIA_STATES.add(PlaybackState.STATE_PAUSED);
|
||||
PAUSED_MEDIA_STATES.add(PlaybackState.STATE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
// Late binding
|
||||
private NotificationEntryManager mEntryManager;
|
||||
@@ -207,6 +216,10 @@ public class NotificationMediaManager implements Dumpable {
|
||||
mPropertiesChangedListener);
|
||||
}
|
||||
|
||||
public static boolean isPlayingState(int state) {
|
||||
return !PAUSED_MEDIA_STATES.contains(state);
|
||||
}
|
||||
|
||||
public void setUpWithPresenter(NotificationPresenter presenter) {
|
||||
mPresenter = presenter;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar;
|
||||
|
||||
import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE;
|
||||
import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
|
||||
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
@@ -48,8 +49,12 @@ import com.android.systemui.statusbar.notification.stack.AnimationProperties;
|
||||
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
||||
import com.android.systemui.statusbar.notification.stack.ViewState;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.statusbar.phone.NotificationIconContainer;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* A notification shelf view that is placed inside the notification scroller. It manages the
|
||||
* overflow icons that don't fit into the regular list anymore.
|
||||
@@ -63,6 +68,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
||||
= SystemProperties.getBoolean("debug.icon_scroll_animations", true);
|
||||
private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag;
|
||||
private static final String TAG = "NotificationShelf";
|
||||
private final KeyguardBypassController mBypassController;
|
||||
|
||||
private NotificationIconContainer mShelfIcons;
|
||||
private int[] mTmp = new int[2];
|
||||
@@ -93,8 +99,12 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
||||
private int mCutoutHeight;
|
||||
private int mGapHeight;
|
||||
|
||||
public NotificationShelf(Context context, AttributeSet attrs) {
|
||||
@Inject
|
||||
public NotificationShelf(@Named(VIEW_CONTEXT) Context context,
|
||||
AttributeSet attrs,
|
||||
KeyguardBypassController keyguardBypassController) {
|
||||
super(context, attrs);
|
||||
mBypassController = keyguardBypassController;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -309,7 +319,10 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
||||
colorTwoBefore = previousColor;
|
||||
transitionAmount = inShelfAmount;
|
||||
}
|
||||
if (isLastChild) {
|
||||
// We don't want to modify the color if the notification is hun'd
|
||||
boolean canModifyColor = mAmbientState.isShadeExpanded()
|
||||
&& !(mAmbientState.isOnKeyguard() && mBypassController.getBypassEnabled());
|
||||
if (isLastChild && canModifyColor) {
|
||||
if (colorOfViewBeforeLast == NO_COLOR) {
|
||||
colorOfViewBeforeLast = ownColorUntinted;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.notification
|
||||
|
||||
import android.content.Context
|
||||
import android.media.MediaMetadata
|
||||
import android.provider.Settings
|
||||
import com.android.keyguard.KeyguardUpdateMonitor
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.statusbar.NotificationMediaManager
|
||||
import com.android.systemui.statusbar.StatusBarState
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController
|
||||
import com.android.systemui.tuner.TunerService
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* A class that automatically creates heads up for important notification when bypassing the
|
||||
* lockscreen
|
||||
*/
|
||||
@Singleton
|
||||
class BypassHeadsUpNotifier @Inject constructor(
|
||||
private val context: Context,
|
||||
private val bypassController: KeyguardBypassController,
|
||||
private val statusBarStateController: StatusBarStateController,
|
||||
private val headsUpManager: HeadsUpManagerPhone,
|
||||
private val mediaManager: NotificationMediaManager,
|
||||
tunerService: TunerService) : StatusBarStateController.StateListener,
|
||||
NotificationMediaManager.MediaListener {
|
||||
|
||||
private lateinit var entryManager: NotificationEntryManager
|
||||
private var currentMediaEntry: NotificationEntry? = null
|
||||
private var enabled = true
|
||||
|
||||
var fullyAwake = false
|
||||
set(value) {
|
||||
field = value
|
||||
if (value) {
|
||||
updateAutoHeadsUp(currentMediaEntry)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
statusBarStateController.addCallback(this)
|
||||
tunerService.addTunable(
|
||||
TunerService.Tunable { _, _ ->
|
||||
enabled = Settings.Secure.getIntForUser(
|
||||
context.contentResolver,
|
||||
Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING,
|
||||
1 /* default */,
|
||||
KeyguardUpdateMonitor.getCurrentUser()) != 0
|
||||
}, Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING)
|
||||
}
|
||||
|
||||
fun setUp(entryManager: NotificationEntryManager) {
|
||||
this.entryManager = entryManager
|
||||
mediaManager.addCallback(this)
|
||||
}
|
||||
|
||||
override fun onMetadataOrStateChanged(metadata: MediaMetadata?, state: Int) {
|
||||
val previous = currentMediaEntry
|
||||
var newEntry = entryManager.notificationData.get(mediaManager.mediaNotificationKey)
|
||||
if (!NotificationMediaManager.isPlayingState(state)) {
|
||||
newEntry = null
|
||||
}
|
||||
if (newEntry?.isSensitive == true) {
|
||||
newEntry = null
|
||||
}
|
||||
currentMediaEntry = newEntry
|
||||
updateAutoHeadsUp(previous)
|
||||
updateAutoHeadsUp(currentMediaEntry)
|
||||
}
|
||||
|
||||
private fun updateAutoHeadsUp(entry: NotificationEntry?) {
|
||||
entry?.let {
|
||||
val autoHeadsUp = it == currentMediaEntry && canAutoHeadsUp()
|
||||
it.isAutoHeadsUp = autoHeadsUp
|
||||
if (autoHeadsUp) {
|
||||
headsUpManager.showNotification(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStatePostChange() {
|
||||
updateAutoHeadsUp(currentMediaEntry)
|
||||
}
|
||||
|
||||
private fun canAutoHeadsUp() : Boolean {
|
||||
if (!enabled) {
|
||||
return false
|
||||
}
|
||||
if (!bypassController.bypassEnabled) {
|
||||
return false
|
||||
}
|
||||
if (statusBarStateController.state != StatusBarState.KEYGUARD) {
|
||||
return false
|
||||
}
|
||||
if (!fullyAwake) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.systemui.statusbar.AlertingNotificationManager;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
@@ -119,12 +118,11 @@ public class NotificationAlertingManager {
|
||||
shouldAlert = mNotificationInterruptionStateProvider.shouldHeadsUp(entry);
|
||||
final boolean wasAlerting = mHeadsUpManager.isAlerting(entry.key);
|
||||
if (wasAlerting) {
|
||||
if (!shouldAlert) {
|
||||
// We don't want this to be interrupting anymore, let's remove it
|
||||
mHeadsUpManager.removeNotification(entry.key,
|
||||
false /* ignoreEarliestRemovalTime */);
|
||||
} else {
|
||||
if (shouldAlert) {
|
||||
mHeadsUpManager.updateNotification(entry.key, alertAgain);
|
||||
} else if (!mHeadsUpManager.isEntryAutoHeadsUpped(entry.key)) {
|
||||
// We don't want this to be interrupting anymore, let's remove it
|
||||
mHeadsUpManager.removeNotification(entry.key, false /* removeImmediately */);
|
||||
}
|
||||
} else if (shouldAlert && alertAgain) {
|
||||
// This notification was updated to be alerting, show it!
|
||||
|
||||
@@ -24,6 +24,8 @@ import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Listener interface for changes sent by NotificationEntryManager.
|
||||
*/
|
||||
@@ -45,7 +47,7 @@ public interface NotificationEntryListener {
|
||||
/**
|
||||
* Called when a new entry is created.
|
||||
*/
|
||||
default void onNotificationAdded(NotificationEntry entry) {
|
||||
default void onNotificationAdded(@NonNull NotificationEntry entry) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +63,7 @@ public interface NotificationEntryListener {
|
||||
/**
|
||||
* Called when a notification was updated, after any filtering of notifications have occurred.
|
||||
*/
|
||||
default void onPostEntryUpdated(NotificationEntry entry) {
|
||||
default void onPostEntryUpdated(@NonNull NotificationEntry entry) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -175,6 +175,7 @@ public final class NotificationEntry {
|
||||
private boolean mHighPriority;
|
||||
private boolean mSensitive = true;
|
||||
private Runnable mOnSensitiveChangedListener;
|
||||
private boolean mAutoHeadsUp;
|
||||
|
||||
public NotificationEntry(StatusBarNotification n) {
|
||||
this(n, null);
|
||||
@@ -670,11 +671,25 @@ public final class NotificationEntry {
|
||||
if (row != null) row.setHeadsUp(shouldHeadsUp);
|
||||
}
|
||||
|
||||
|
||||
public void setHeadsUpAnimatingAway(boolean animatingAway) {
|
||||
if (row != null) row.setHeadsUpAnimatingAway(animatingAway);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that this notification was automatically heads upped. This happens for example when
|
||||
* the user bypasses the lockscreen and media is playing.
|
||||
*/
|
||||
public void setAutoHeadsUp(boolean autoHeadsUp) {
|
||||
mAutoHeadsUp = autoHeadsUp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if this notification was automatically heads upped. This happens for example when
|
||||
* * the user bypasses the lockscreen and media is playing.
|
||||
*/
|
||||
public boolean isAutoHeadsUp() {
|
||||
return mAutoHeadsUp;
|
||||
}
|
||||
|
||||
public boolean mustStayOnScreen() {
|
||||
return row != null && row.mustStayOnScreen();
|
||||
|
||||
@@ -2698,6 +2698,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
l.setAlpha(1.0f);
|
||||
l.setLayerType(LAYER_TYPE_NONE, null);
|
||||
}
|
||||
} else {
|
||||
setHeadsUpAnimatingAway(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -837,7 +837,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mAmbientState.isDozing() || anySectionHasVisibleChild) {
|
||||
boolean shouldDrawBackground;
|
||||
if (mKeyguardBypassController.getBypassEnabled() && onKeyguard()) {
|
||||
shouldDrawBackground = isPulseExpanding();
|
||||
} else {
|
||||
shouldDrawBackground = !mAmbientState.isDozing() || anySectionHasVisibleChild;
|
||||
}
|
||||
if (shouldDrawBackground) {
|
||||
drawBackgroundRects(canvas, left, right, top, backgroundTopAnimationOffset);
|
||||
}
|
||||
|
||||
@@ -3396,10 +3402,20 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
|
||||
for (Pair<ExpandableNotificationRow, Boolean> eventPair : mHeadsUpChangeAnimations) {
|
||||
ExpandableNotificationRow row = eventPair.first;
|
||||
boolean isHeadsUp = eventPair.second;
|
||||
if (isHeadsUp != row.isHeadsUp()) {
|
||||
// For cases where we have a heads up showing and appearing again we shouldn't
|
||||
// do the animations at all.
|
||||
continue;
|
||||
}
|
||||
int type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_OTHER;
|
||||
boolean onBottom = false;
|
||||
boolean pinnedAndClosed = row.isPinned() && !mIsExpanded;
|
||||
if (!mIsExpanded && !isHeadsUp) {
|
||||
boolean performDisappearAnimation = !mIsExpanded
|
||||
// Only animate if we still have pinned heads up, otherwise we just have the
|
||||
// regular collapse animation of the lock screen
|
||||
|| (mKeyguardBypassController.getBypassEnabled() && onKeyguard()
|
||||
&& mHeadsUpManager.hasPinnedHeadsUp());
|
||||
if (performDisappearAnimation && !isHeadsUp) {
|
||||
type = row.wasJustClicked()
|
||||
? AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
|
||||
: AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
|
||||
@@ -6246,6 +6262,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
|
||||
mAmbientState.onDragFinished(animView);
|
||||
updateContinuousShadowDrawing();
|
||||
updateContinuousBackgroundDrawing();
|
||||
if (animView instanceof ExpandableNotificationRow) {
|
||||
ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
|
||||
if (row.isPinned() && !canChildBeDismissed(row)
|
||||
&& row.getStatusBarNotification().getNotification().fullScreenIntent
|
||||
== null) {
|
||||
mHeadsUpManager.removeNotification(row.getStatusBarNotification().getKey(),
|
||||
true /* removeImmediately */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -546,12 +546,12 @@ public class StackScrollAlgorithm {
|
||||
ExpandableViewState topState =
|
||||
topHeadsUpEntry == null ? null : topHeadsUpEntry.getViewState();
|
||||
if (topState != null && !isTopEntry && (!mIsExpanded
|
||||
|| unmodifiedEndLocation < topState.yTranslation + topState.height)) {
|
||||
|| unmodifiedEndLocation > topState.yTranslation + topState.height)) {
|
||||
// Ensure that a headsUp doesn't vertically extend further than the heads-up at
|
||||
// the top most z-position
|
||||
childState.height = row.getIntrinsicHeight();
|
||||
childState.yTranslation = topState.yTranslation + topState.height
|
||||
- childState.height;
|
||||
childState.yTranslation = Math.min(topState.yTranslation + topState.height
|
||||
- childState.height, childState.yTranslation);
|
||||
}
|
||||
|
||||
// heads up notification show and this row is the top entry of heads up
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.NotificationShelf;
|
||||
import com.android.systemui.statusbar.StatusBarIconView;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
||||
|
||||
@@ -451,7 +452,11 @@ public class StackStateAnimator {
|
||||
if (row.isDismissed()) {
|
||||
needsAnimation = false;
|
||||
}
|
||||
StatusBarIconView icon = row.getEntry().icon;
|
||||
NotificationEntry entry = row.getEntry();
|
||||
StatusBarIconView icon = entry.icon;
|
||||
if (entry.centeredIcon != null && entry.centeredIcon.getParent() != null) {
|
||||
icon = entry.centeredIcon;
|
||||
}
|
||||
if (icon.getParent() != null) {
|
||||
icon.getLocationOnScreen(mTmpLocation);
|
||||
float iconPosition = mTmpLocation[0] - icon.getTranslationX()
|
||||
|
||||
@@ -32,7 +32,6 @@ import android.view.ViewTreeObserver;
|
||||
import androidx.collection.ArraySet;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.ScreenDecorations;
|
||||
@@ -67,6 +66,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
final int mExtensionTime;
|
||||
private final StatusBarStateController mStatusBarStateController;
|
||||
private final KeyguardBypassController mBypassController;
|
||||
private final int mAutoHeadsUpNotificationDecay;
|
||||
private View mStatusBarWindowView;
|
||||
private NotificationGroupManager mGroupManager;
|
||||
private VisualStabilityManager mVisualStabilityManager;
|
||||
@@ -81,6 +81,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
private boolean mTrackingHeadsUp;
|
||||
private HashSet<String> mSwipedOutKeys = new HashSet<>();
|
||||
private HashSet<NotificationEntry> mEntriesToRemoveAfterExpand = new HashSet<>();
|
||||
private HashSet<String> mKeysToRemoveWhenLeavingKeyguard = new HashSet<>();
|
||||
private ArraySet<NotificationEntry> mEntriesToRemoveWhenReorderingAllowed
|
||||
= new ArraySet<>();
|
||||
private boolean mIsExpanded;
|
||||
@@ -121,6 +122,8 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
mAutoDismissNotificationDecayDozing = resources.getInteger(
|
||||
R.integer.heads_up_notification_decay_dozing);
|
||||
mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
|
||||
mAutoHeadsUpNotificationDecay = resources.getInteger(
|
||||
R.integer.auto_heads_up_notification_decay);
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mStatusBarStateController.addCallback(this);
|
||||
mBypassController = bypassController;
|
||||
@@ -231,7 +234,16 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int newState) {
|
||||
boolean wasKeyguard = mStatusBarState == StatusBarState.KEYGUARD;
|
||||
boolean isKeyguard = newState == StatusBarState.KEYGUARD;
|
||||
mStatusBarState = newState;
|
||||
if (wasKeyguard && !isKeyguard && mKeysToRemoveWhenLeavingKeyguard.size() != 0) {
|
||||
String[] keys = mKeysToRemoveWhenLeavingKeyguard.toArray(new String[0]);
|
||||
for (String key : keys) {
|
||||
removeAlertEntry(key);
|
||||
}
|
||||
mKeysToRemoveWhenLeavingKeyguard.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -245,6 +257,15 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntryAutoHeadsUpped(String key) {
|
||||
HeadsUpEntryPhone headsUpEntryPhone = getHeadsUpEntryPhone(key);
|
||||
if (headsUpEntryPhone == null) {
|
||||
return false;
|
||||
}
|
||||
return headsUpEntryPhone.isAutoHeadsUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that we are exiting the headsUp pinned mode, but some notifications might still be
|
||||
* animating out. This is used to keep the touchable regions in a sane state.
|
||||
@@ -420,6 +441,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
|
||||
@Override
|
||||
protected void onAlertEntryRemoved(AlertEntry alertEntry) {
|
||||
mKeysToRemoveWhenLeavingKeyguard.remove(alertEntry.mEntry.key);
|
||||
super.onAlertEntryRemoved(alertEntry);
|
||||
mEntryPool.release((HeadsUpEntryPhone) alertEntry);
|
||||
}
|
||||
@@ -479,6 +501,11 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
*/
|
||||
private boolean extended;
|
||||
|
||||
/**
|
||||
* Was this entry received while on keyguard
|
||||
*/
|
||||
private boolean mIsAutoHeadsUp;
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isSticky() {
|
||||
@@ -494,10 +521,12 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
mEntriesToRemoveWhenReorderingAllowed.add(entry);
|
||||
mVisualStabilityManager.addReorderingAllowedCallback(
|
||||
HeadsUpManagerPhone.this);
|
||||
} else if (!mTrackingHeadsUp) {
|
||||
removeAlertEntry(entry.key);
|
||||
} else {
|
||||
} else if (mTrackingHeadsUp) {
|
||||
mEntriesToRemoveAfterExpand.add(entry);
|
||||
} else if (mIsAutoHeadsUp && mStatusBarState == StatusBarState.KEYGUARD) {
|
||||
mKeysToRemoveWhenLeavingKeyguard.add(entry.key);
|
||||
} else {
|
||||
removeAlertEntry(entry.key);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -506,6 +535,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
|
||||
@Override
|
||||
public void updateEntry(boolean updatePostTime) {
|
||||
mIsAutoHeadsUp = mEntry.isAutoHeadsUp();
|
||||
super.updateEntry(updatePostTime);
|
||||
|
||||
if (mEntriesToRemoveAfterExpand.contains(mEntry)) {
|
||||
@@ -514,6 +544,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
if (mEntriesToRemoveWhenReorderingAllowed.contains(mEntry)) {
|
||||
mEntriesToRemoveWhenReorderingAllowed.remove(mEntry);
|
||||
}
|
||||
mKeysToRemoveWhenLeavingKeyguard.remove(mEntry.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -548,6 +579,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
super.reset();
|
||||
mMenuShownPinned = false;
|
||||
extended = false;
|
||||
mIsAutoHeadsUp = false;
|
||||
}
|
||||
|
||||
private void extendPulse() {
|
||||
@@ -557,14 +589,36 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(AlertEntry alertEntry) {
|
||||
HeadsUpEntryPhone headsUpEntry = (HeadsUpEntryPhone) alertEntry;
|
||||
boolean autoShown = isAutoHeadsUp();
|
||||
boolean otherAutoShown = headsUpEntry.isAutoHeadsUp();
|
||||
if (autoShown && !otherAutoShown) {
|
||||
return 1;
|
||||
} else if (!autoShown && otherAutoShown) {
|
||||
return -1;
|
||||
}
|
||||
return super.compareTo(alertEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long calculateFinishTime() {
|
||||
return mPostTime + getDecayDuration() + (extended ? mExtensionTime : 0);
|
||||
}
|
||||
|
||||
private int getDecayDuration() {
|
||||
return mStatusBarStateController.isDozing() ? mAutoDismissNotificationDecayDozing
|
||||
: getRecommendedHeadsUpTimeoutMs();
|
||||
if (mStatusBarStateController.isDozing()) {
|
||||
return mAutoDismissNotificationDecayDozing;
|
||||
} else if (isAutoHeadsUp()) {
|
||||
return getRecommendedHeadsUpTimeoutMs(mAutoHeadsUpNotificationDecay);
|
||||
} else {
|
||||
return getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAutoHeadsUp() {
|
||||
return mIsAutoHeadsUp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ import com.android.systemui.statusbar.phone.ScrimController.ScrimVisibility;
|
||||
import com.android.systemui.statusbar.policy.AccessibilityController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardMonitor;
|
||||
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
|
||||
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -67,7 +68,8 @@ import javax.inject.Named;
|
||||
public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChangedListener,
|
||||
StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener,
|
||||
UnlockMethodCache.OnUnlockMethodChangedListener,
|
||||
NotificationWakeUpCoordinator.WakeUpListener, ViewTreeObserver.OnPreDrawListener {
|
||||
NotificationWakeUpCoordinator.WakeUpListener, ViewTreeObserver.OnPreDrawListener,
|
||||
OnHeadsUpChangedListener {
|
||||
|
||||
private static final int STATE_LOCKED = 0;
|
||||
private static final int STATE_LOCK_OPEN = 1;
|
||||
@@ -82,6 +84,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
|
||||
private final KeyguardMonitor mKeyguardMonitor;
|
||||
private final KeyguardBypassController mBypassController;
|
||||
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
|
||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||
|
||||
private int mLastState = 0;
|
||||
private boolean mForceUpdate;
|
||||
@@ -94,7 +97,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
|
||||
private boolean mDocked;
|
||||
private int mIconColor;
|
||||
private float mDozeAmount;
|
||||
private boolean mBouncerShowing;
|
||||
private boolean mBouncerShowingScrimmed;
|
||||
private boolean mWakeAndUnlockRunning;
|
||||
private boolean mKeyguardShowing;
|
||||
private boolean mShowingLaunchAffordance;
|
||||
@@ -155,7 +158,8 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
|
||||
KeyguardBypassController bypassController,
|
||||
NotificationWakeUpCoordinator wakeUpCoordinator,
|
||||
KeyguardMonitor keyguardMonitor,
|
||||
@Nullable DockManager dockManager) {
|
||||
@Nullable DockManager dockManager,
|
||||
HeadsUpManagerPhone headsUpManager) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
|
||||
@@ -167,6 +171,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
|
||||
mWakeUpCoordinator = wakeUpCoordinator;
|
||||
mKeyguardMonitor = keyguardMonitor;
|
||||
mDockManager = dockManager;
|
||||
mHeadsUpManager = headsUpManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -296,11 +301,13 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
|
||||
boolean onAodNotPulsingOrDocked = mDozing && (!mPulsing || mDocked);
|
||||
boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning
|
||||
|| mShowingLaunchAffordance;
|
||||
if (mBypassController.getBypassEnabled()
|
||||
&& mStatusBarStateController.getState() == StatusBarState.KEYGUARD
|
||||
&& !mWakeUpCoordinator.getNotificationsFullyHidden()
|
||||
&& !mBouncerShowing) {
|
||||
invisible = true;
|
||||
if (mBypassController.getBypassEnabled() && !mBouncerShowingScrimmed) {
|
||||
if (mHeadsUpManager.isHeadsUpGoingAway()
|
||||
|| mHeadsUpManager.hasPinnedHeadsUp()
|
||||
|| (mStatusBarStateController.getState() == StatusBarState.KEYGUARD
|
||||
&& !mWakeUpCoordinator.getNotificationsFullyHidden())) {
|
||||
invisible = true;
|
||||
}
|
||||
}
|
||||
boolean wasInvisible = getVisibility() == INVISIBLE;
|
||||
if (invisible != wasInvisible) {
|
||||
@@ -408,8 +415,8 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
|
||||
}
|
||||
}
|
||||
|
||||
public void setBouncerShowing(boolean bouncerShowing) {
|
||||
mBouncerShowing = bouncerShowing;
|
||||
public void setBouncerShowingScrimmed(boolean bouncerShowing) {
|
||||
mBouncerShowingScrimmed = bouncerShowing;
|
||||
if (mBypassController.getBypassEnabled()) {
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ public class NotificationIconAreaController implements DarkReceiver,
|
||||
if (onlyShowCenteredIcon) {
|
||||
return isCenteredNotificationIcon;
|
||||
}
|
||||
if (hideCenteredIcon && isCenteredNotificationIcon) {
|
||||
if (hideCenteredIcon && isCenteredNotificationIcon && !entry.isRowHeadsUp()) {
|
||||
return false;
|
||||
}
|
||||
if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) {
|
||||
|
||||
@@ -80,6 +80,7 @@ import android.metrics.LogMaker;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Debug;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
@@ -193,6 +194,7 @@ import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||
import com.android.systemui.statusbar.VibratorHelper;
|
||||
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
|
||||
import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
|
||||
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
||||
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
|
||||
import com.android.systemui.statusbar.notification.NotificationClicker;
|
||||
@@ -373,6 +375,8 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
KeyguardBypassController mKeyguardBypassController;
|
||||
@Inject
|
||||
protected HeadsUpManagerPhone mHeadsUpManager;
|
||||
@Inject
|
||||
BypassHeadsUpNotifier mBypassHeadsUpNotifier;
|
||||
@Nullable
|
||||
@Inject
|
||||
protected KeyguardLiftController mKeyguardLiftController;
|
||||
@@ -633,6 +637,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mGutsManager = Dependency.get(NotificationGutsManager.class);
|
||||
mMediaManager = Dependency.get(NotificationMediaManager.class);
|
||||
mEntryManager = Dependency.get(NotificationEntryManager.class);
|
||||
mBypassHeadsUpNotifier.setUp(mEntryManager);
|
||||
mNotificationInterruptionStateProvider =
|
||||
Dependency.get(NotificationInterruptionStateProvider.class);
|
||||
mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class);
|
||||
@@ -649,7 +654,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance();
|
||||
if (sliceProvider != null) {
|
||||
sliceProvider.initDependencies(mMediaManager, mStatusBarStateController,
|
||||
mKeyguardBypassController);
|
||||
mKeyguardBypassController, DozeParameters.getInstance(mContext));
|
||||
} else {
|
||||
Log.w(TAG, "Cannot init KeyguardSliceProvider dependencies");
|
||||
}
|
||||
@@ -1154,8 +1159,9 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
|
||||
private void inflateShelf() {
|
||||
mNotificationShelf =
|
||||
(NotificationShelf) LayoutInflater.from(mContext).inflate(
|
||||
R.layout.status_bar_notification_shelf, mStackScroller, false);
|
||||
(NotificationShelf) mInjectionInflater.injectable(
|
||||
LayoutInflater.from(mContext)).inflate(
|
||||
R.layout.status_bar_notification_shelf, mStackScroller, false);
|
||||
mNotificationShelf.setOnClickListener(mGoToLockedShadeListener);
|
||||
}
|
||||
|
||||
@@ -3576,7 +3582,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mBouncerShowing = bouncerShowing;
|
||||
mKeyguardBypassController.setBouncerShowing(bouncerShowing);
|
||||
mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
|
||||
mStatusBarWindow.setBouncerShowing(bouncerShowing);
|
||||
mStatusBarWindow.setBouncerShowingScrimmed(isBouncerShowingScrimmed());
|
||||
if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
|
||||
updateHideIconsForBouncer(true /* animate */);
|
||||
mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
|
||||
@@ -3629,6 +3635,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
notifyHeadsUpGoingToSleep();
|
||||
dismissVolumeDialog();
|
||||
mWakeUpCoordinator.setFullyAwake(false);
|
||||
mBypassHeadsUpNotifier.setFullyAwake(false);
|
||||
mKeyguardBypassController.onStartedGoingToSleep();
|
||||
}
|
||||
|
||||
@@ -3653,6 +3660,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
@Override
|
||||
public void onFinishedWakingUp() {
|
||||
mWakeUpCoordinator.setFullyAwake(true);
|
||||
mBypassHeadsUpNotifier.setFullyAwake(true);
|
||||
mWakeUpCoordinator.setWakingUp(false);
|
||||
if (mLaunchCameraWhenFinishedWaking) {
|
||||
mNotificationPanel.launchCamera(false /* animate */, mLastCameraLaunchSource);
|
||||
|
||||
@@ -525,9 +525,9 @@ public class StatusBarWindowView extends FrameLayout {
|
||||
mBypassController = bypassController;
|
||||
}
|
||||
|
||||
public void setBouncerShowing(boolean bouncerShowing) {
|
||||
public void setBouncerShowingScrimmed(boolean bouncerShowing) {
|
||||
if (mLockIcon != null) {
|
||||
mLockIcon.setBouncerShowing(bouncerShowing);
|
||||
mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -356,6 +356,10 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
}
|
||||
|
||||
public boolean isEntryAutoHeadsUpped(String key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a notification and how long it is in a heads up mode. It also manages its
|
||||
* lifecycle automatically when created.
|
||||
@@ -416,16 +420,17 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
|
||||
|
||||
@Override
|
||||
protected long calculateFinishTime() {
|
||||
return mPostTime + getRecommendedHeadsUpTimeoutMs();
|
||||
return mPostTime + getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user-preferred or default timeout duration. The larger one will be returned.
|
||||
* @return milliseconds before auto-dismiss
|
||||
* @param requestedTimeout
|
||||
*/
|
||||
protected int getRecommendedHeadsUpTimeoutMs() {
|
||||
protected int getRecommendedHeadsUpTimeoutMs(int requestedTimeout) {
|
||||
return mAccessibilityMgr.getRecommendedTimeoutMillis(
|
||||
mAutoDismissNotificationDecay,
|
||||
requestedTimeout,
|
||||
AccessibilityManager.FLAG_CONTENT_CONTROLS
|
||||
| AccessibilityManager.FLAG_CONTENT_ICONS
|
||||
| AccessibilityManager.FLAG_CONTENT_TEXT);
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.android.systemui.qs.QSFooterImpl;
|
||||
import com.android.systemui.qs.QSPanel;
|
||||
import com.android.systemui.qs.QuickQSPanel;
|
||||
import com.android.systemui.qs.QuickStatusBarHeader;
|
||||
import com.android.systemui.statusbar.NotificationShelf;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
||||
import com.android.systemui.statusbar.phone.LockIcon;
|
||||
import com.android.systemui.statusbar.phone.NotificationPanelView;
|
||||
@@ -137,6 +138,11 @@ public class InjectionInflationController {
|
||||
*/
|
||||
QSCarrierGroup createQSCarrierGroup();
|
||||
|
||||
/**
|
||||
* Creates the Shelf.
|
||||
*/
|
||||
NotificationShelf creatNotificationShelf();
|
||||
|
||||
/**
|
||||
* Creates the KeyguardClockSwitch.
|
||||
*/
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.NotificationMediaManager;
|
||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
import com.android.systemui.util.wakelock.SettableWakeLock;
|
||||
@@ -84,6 +85,8 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
|
||||
private SettableWakeLock mMediaWakeLock;
|
||||
@Mock
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
@Mock
|
||||
private DozeParameters mDozeParameters;
|
||||
private TestableKeyguardSliceProvider mProvider;
|
||||
private boolean mIsZenMode;
|
||||
|
||||
@@ -94,7 +97,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
|
||||
mProvider = new TestableKeyguardSliceProvider();
|
||||
mProvider.attachInfo(getContext(), null);
|
||||
mProvider.initDependencies(mNotificationMediaManager, mStatusBarStateController,
|
||||
mKeyguardBypassController);
|
||||
mKeyguardBypassController, mDozeParameters);
|
||||
SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST)));
|
||||
}
|
||||
|
||||
@@ -130,6 +133,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
|
||||
MediaMetadata metadata = mock(MediaMetadata.class);
|
||||
when(metadata.getText(any())).thenReturn("metadata");
|
||||
when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
|
||||
when(mDozeParameters.getAlwaysOn()).thenReturn(true);
|
||||
mProvider.onMetadataOrStateChanged(metadata, PlaybackState.STATE_PLAYING);
|
||||
mProvider.onBindSlice(mProvider.getUri());
|
||||
verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_TITLE));
|
||||
|
||||
Reference in New Issue
Block a user